🚀

Launchable Advent Calendar 15日目 - Zero Input Subsetting

2022/12/15に公開

Launchableの各機能の利用方法を紹介する Launchable Advent Calendar 15日目です。

はじめに

今日はZero Input Subsetting(ZIS)とその利用方法について紹介します。(docs)

Day 6でPredictive Test Selection(PTS)について紹介しました。
そこでPTSに実行するテスト一覧をインプットとして渡す必要があると説明しました。
しかし、テスト環境によってはテスト一覧自体を用意することが難しい場合があります。

それを解決するのがZISになります。

Zero Input Subsetting (ZIS)

ZISは launchable subset コマンドの --get-tests-from-previous-sessions オプションと --output-exclusion-rules オプションを組み合わせて実現します。

コマンドとしてはこのようになります。

$ launchable subset --target 20% \
    --get-tests-from-previous-sessions \
    --output-exclusion-rules \
    maven > launchable-exclude.txt

まずは各オプションと利用方法について説明します。

--get-tests-from-previous-sessionsオプション

--get-tests-from-previous-sessions オプションは過去にレポートしたテスト結果をから launchable subset へ渡すテスト一覧をLaunchable側で用意するオプションになります。

これまではmavenプラグインの場合 launchable subset --target100% maven src/test/java とテストがあるディレクトリをコマンドに渡す必要がありました。
以下の例ではディレクトリを渡していなくても launchable subset コマンドでPTSによって選ばれたテストが返っています。

$ launchable subset --target 100% --get-tests-from-previous-sessions maven
example.SubTest
example.MulTest
example.DivTest
example.AddTest
Launchable created subset 397107 for build ignore-new-tests-example (test session 1619454) in workspace konboi/advent-calendar-2022

|           |   Candidates |   Estimated duration (%) |   Estimated duration (min) |
|-----------|--------------|--------------------------|----------------------------|
| Subset    |            4 |                      100 |                6.66667e-05 |
| Remainder |            0 |                        0 |                0           |
|           |              |                          |                            |
| Total     |            4 |                      100 |                6.66667e-05 |

Run `launchable inspect subset --subset-id 397107` to view full subset details

ただし、このオプションだけだと不十分です。--get-tests-from-previous-sessions オプションの欠点として新規に追加されたテストはこのオプションでは取得できません。

Day 14で追加したテストを使って挙動を確認してみましょう。
ローカルにはテストファイルが5つあるにも関わらず --get-tests-from-previous-sessions オプションを指定すると4ファイルしか返ってこないのが確認できます。

$ launchable subset --target 100% maven src/test/java
example.Add3Test
example.MulTest
example.SubTest
example.AddTest
example.DivTest
Launchable created subset 397138 for build ignore-new-tests-example (test session 1619454) in workspace konboi/advent-calendar-2022

|           |   Candidates |   Estimated duration (%) |   Estimated duration (min) |
|-----------|--------------|--------------------------|----------------------------|
| Subset    |            5 |                      100 |                  0.0716833 |
| Remainder |            0 |                        0 |                  0         |
|           |              |                          |                            |
| Total     |            5 |                      100 |                  0.0716833 |

Run `launchable inspect subset --subset-id 397138` to view full subset details

$ launchable subset --target 100% --get-tests-from-previous-sessions maven
example.SubTest
example.MulTest
example.DivTest
example.AddTest
Launchable created subset 397139 for build ignore-new-tests-example (test session 1619454) in workspace konboi/advent-calendar-2022

|           |   Candidates |   Estimated duration (%) |   Estimated duration (min) |
|-----------|--------------|--------------------------|----------------------------|
| Subset    |            4 |                      100 |                6.66667e-05 |
| Remainder |            0 |                        0 |                0           |
|           |              |                          |                            |
| Total     |            4 |                      100 |                6.66667e-05 |

Run `launchable inspect subset --subset-id 397139` to view full subset details

--output-exclusion-rules

続いて --output-exclusion-rules オプションについて説明します。
このオプションを指定すると launchable subset の出力がテストすべきテスト一覧からテストすべきでないリストに変更されます。

想定利用シーンとしては、出力されたリストをテストランナーのテストしない/除くオプション(例 ignore , exclude オプション)に渡します。

この例では example.Add3Testexample.MulTest をテストすべきリストとして launchable subset コマンドが出力しています。

$ launchable subset --target 20% maven src/test/java
example.Add3Test
example.MulTest
Launchable created subset 397150 for build ignore-new-tests-example (test session 1619454) in workspace konboi/advent-calendar-2022

|           |   Candidates |   Estimated duration (%) |   Estimated duration (min) |
|-----------|--------------|--------------------------|----------------------------|
| Subset    |            2 |                   13.129 |                  0.01335   |
| Remainder |            3 |                   86.871 |                  0.0883333 |
|           |              |                          |                            |
| Total     |            5 |                  100     |                  0.101683  |

Run `launchable inspect subset --subset-id 397150` to view full subset details

一方 --output-exclusion-rules オプションをつけた場合は example.SubTest, example.AddTest, example.DivTest をテストすべきでないリストとして出力しています。

$ launchable subset --target 20% --output-exclusion-rules maven src/test/java
example.SubTest
example.AddTest
example.DivTest
Launchable created subset 397149 for build ignore-new-tests-example (test session 1619454) in workspace konboi/advent-calendar-2022

|           |   Candidates |   Estimated duration (%) |   Estimated duration (min) |
|-----------|--------------|--------------------------|----------------------------|
| Subset    |            2 |                  7.70414 |                  0.0100167 |
| Remainder |            3 |                 92.2959  |                  0.12      |
|           |              |                          |                            |
| Total     |            5 |                100       |                  0.130017  |

Run `launchable inspect subset --subset-id 397149` to view full subset details

ZIS

ZISは --get-tests-from-previous-sessions オプションで過去のテスト結果からテストすべき一覧を取得する。--output-exclusion-rules オプションでテストすべきでないリストに変更する。

これをテストランナーのテストから除くオプションに渡す事で新しく追加したテストも漏れなくテストできるという訳です。

使用しているテストランナーがテストを除くオプションに対応していない場合ZISを利用できません。

GitHub Actionsでの例

Day 6の設定を元にSubsetの実行をZISを利用したものに変更します。

変更点としては

  • launchable subset コマンドに --get-tests-from-previous-sessions, --output-exclusion-rules オプションを使用しテストしないリストを作成。
  • mvn へのオプションを -Dsurefire.includesFile から -Dsurefire.excludesFile へ変更し、リストに含まれているテスト以外のテストを実行する形に変更する。

の2点になります。

ci.yaml
       - name: record build
         run: launchable record build --name ${GITHUB_RUN_ID}
       - name: subset
-        run: launchable subset --target 80% maven src/test/java > launchable-subset.txt
+        run: launchable subset --target 80% --get-tests-from-previous-sessions --output-exclusion-rules maven > launchable-exclude.txt
       - name: Run tests
-        run: mvn test -Dsurefire.includesFile=launchable-subset.txt
+        run: mvn test -Dsurefire.excludesFile=launchable-exclude.txt
       - name: launchable record tests
         run: launchable record tests maven target/surefire-reports/TEST-example.*.xml
         if: always()

サンプルPR

さいごに

本日はZero Input Subsettingについて紹介しました。
明日はテストの並列実行を実現する Split Subsetと launchable split-subset コマンドについて紹介します。

Discussion