Upgrade to Pro — share decks privately, control downloads, hide ads and more …

差分ベースで効率的にテストを実行してみる

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for Shia Shia
October 21, 2022

 差分ベースで効率的にテストを実行してみる

Avatar for Shia

Shia

October 21, 2022
Tweet

More Decks by Shia

Other Decks in Technology

Transcript

  1. order_spec.rb - テストとテスト実行に使用されるロジックの依存を計算 (事前処理) - 差分からの実行すべきテストを算出する (毎テスト実行) 本当に必要なテストだけを実行する Commit A

    Commit B book.rb order.rb book_spec.rb order_spec.rb テストとテスト実行に使用される ロジックの依存情報 order.rb +++--- テスト選択機 book.rb order.rb book_spec.rb order_spec.rb
  2. テストが依存しているロジックをどういう解像度で表すか - method based - 1 test associated to n

    methods - 粒度が小さい代わりにテスト選択が複雑 - コアロジックに絡む場合の効率がいい - file based <- 今回の話 - 1 test file to n source files - 粒度が大きい代わりにテスト選択が簡単 - コアロジックに絡む場合の効率が悪い 依存情報の解像度
  3. 手法候補 - 静的分析ベース - Ruby だとヒューリスティックがたくさんになりメンテコストが現実味 がない。 Ruby 3.0 で入った型に期待。

    - 動的分析ベース <- 今回の話 - 速度面で不安があるけどとにかく楽 - 機械学習ベース - モデルの精度を実用段階まであげるところから始めないといけないので 検証の道のりが長い
  4. - rotoscope - Shopify で使ってるらしい。採択 - calleree - ko1 さんが作ったもの

    - 呼び出し先のローケーションが取れて嬉しい - 実験時点では今回のテスト環境である Ruby 2.7 ではバグがあったため 未採択 - coverage - 実行したコードを記録するためのライブラリ - erb などのテンプレートのロギングができない - 実験終わってから気づいてしまったので未採択(速度計測はあり) 依存情報ロギングに使えるツール
  5. 実験 - 知りたいこと - 事前に計算しておくコストの重さ - 10倍遅くなるとかなら話にならない - 実際どれくらいテストを絞れますか -

    絞れたとして選択した数が平均で全体数の 80% ならあまり嬉しくない - 絞れないケースが多くても微妙 - 正しいテストが選ばれてますか - 選ばれるべきだが選ばれてないと困る - 正しいか人の確認が必要
  6. - 普通の Rails アプリケーション - テストの数は 10k+ で全体実行だと手元(MBP 14' 2021)で

    2hr+ - file based 依存情報を利用 実験 - 対象プロジェクト
  7. - 1. 計算した依存情報から PR ごとに選択されたテストの数 - 障害を起こしていない連続している PR 30件 -

    base branch … pr branch の差分を利用 - 2. 依存情報を作るのにかかる時間測定 - 有効にしている時とそうじゃない時の比較 - 3. 選択されるべきテストの選択漏れはないか 実験用で作った gem: https://github.com/riseshia/affected_tests 最小 poc: https://github.com/riseshia/test-filtering-poc 実験 - 計測対象
  8. 実験 - 実験結果1(テスト選択効率) - 全件実行になったもの - テストなしのワンショット用コード / アセット /

    設定の変更 - bundle update PR(ボットからの定期実行) - 40% 以上選択したもの - ビジネスロジックのコアにあるものが変更されている Shopify で出している結果とあまり変わらない。つまりこのサイズでも アプローチそのものは有効っと考えられる 
  9. 全体テストの一部だけを数回実行して平均をだし比較 - ロギングなし -> 8min - rotoscope -> 10.5min (31%増加)

    - coverage -> 8.5min (6%増加) 実験 - 実験結果2(依存情報ロギングによる速度低下)
  10. 知りたいこと、わかった? - 事前に計算しておくコストの重さ - 実行速度面では大丈夫そう - インフラコスト面では 1 依存情報生成に対して 2-3回実行テスト数を絞

    れたらが取れそう - 実際どれくらいテストを絞れますか - 開発体験という意味だともう少し効率あげたいかも - 正しいテストが選ばれてますか - 少なくとも実験上で選ばれた差分では問題のある事例は見つからず - 動的分析でも安全!という保証はできない
  11. 動的分析の感想 - 実用上呼び出し元側のローケーションだけを収集してもほぼ問題ない - ほとんどの最終的な辿り着き先は別の gem/標準 lib メソッド - rotoscope

    はデフォルトでは呼び出したメソッドは教えてくれが、その ローケーション情報を提供しない - 検知できないものは確かにあるが、実用上でクリティカルとは思えない - e.g. モジュール内部の定数参照 - e.g. ActiveRecord モデルの属性参照 - 頑張れば全体選択の頻度は下げられそう - アセットへの参照...
  12. 利用体験への感想 - テスト環境セットアップにかかる速度の重要性があがる - e.g. セットアップに3分かけてテストが 10秒で終わってしまうと結局体 感として遅いまま - CI

    が並列数を実行中に変更可能じゃなければテスト数によって並列 数を変更できないのでやや非効率 - e.g. 選択したテストファイル数がノード数より少ないとなんもしない ノードが発生する
  13. 使い道への考察 3. 手元で PR を提出する前に利用する - 変更の影響範囲を調べるために使える - 選択されたテスト数が少ない -

    PR で意図してないところへの影響によるテスト失敗が見つかったが CI 待ちで開発速度が落ちるのはよくあるケース - 手元で完結できて便利 - 選択されるテスト数が多い - CI 上の並列実行に任せる - プロジェクトによって手軽に実行できるテスト数は違うので価値があ るかは試してみるしかない