Launchable Advent Calendar 16日目 - Split Subset
Launchableの各機能の利用方法を紹介する Launchable Advent Calendar 16日目です。
はじめに
16日目はSplit Subsetについて説明します。(docs)
Split Subsetは並列でテスト実行するのを助ける機能です。
テストランナーに並列でテストを実行する機能が備わっていない場合でも並列でのテストが可能になります。複数台のマシンを利用して並列でテストする際のテストケースの重複や実行時間の偏りなどの煩わしさもありません。
Split Subset
使用する主なコマンドは launchable subset
, launchable split-subset
コマンドになります。
また、テスト結果のレポート時に launchable record tests
コマンドで --subset-id
オプションを使用します。
実行する流れとしては、今までと同じように launchable subset
コマンドを使用しPredictive Test Selection(PTS) を行います。1つ異なるのが --split
オプションを使用する点です。
このオプションを使用することでテストすべきリストを出力していたものが launchable split-subset
の --subset-id
オプションに渡すSubset IDを出力するようになります。
出力されたSubset IDを使用して launchable split-subset
を実行します。
その際 --bin
オプション使用し、PTSの結果を何分割にするのか、分割したうちのどれを取得するのかを指定します。
こちらはPTSを4分割にし、1つ目を使用する例になります。
$ launchable subset --target 100% --split maven src/test/java
subset/397825
Launchable created subset 397825 for build ignore-new-tests-example (test session 1619454) in workspace konboi/advent-calendar-2022
| | Candidates | Estimated duration (%) | Estimated duration (min) |
|-----------|--------------|--------------------------|----------------------------|
| Subset | 4 | 100 | 0.0983333 |
| Remainder | 0 | 0 | 0 |
| | | | |
| Total | 4 | 100 | 0.0983333 |
Run `launchable inspect subset --subset-id 397825` to view full subset details
$ launchable split-subset --subset-id subset/397825 --bin 1/4 maven
example.MulTest
...
# テスト結果のレポート
$ launchable record tests --subset-id subset/397825 maven target/surefire-reports/TEST-example.*.xml
以下は1回目の実行ではPTSの結果を4分割にしたうちの2つ目を取得。2回目の実行では2分割したうちの1つ目、最後の実行では2分割したうちの2つ目を取得する。という例になります。
$ launchable split-subset --subset-id subset/397825 --bin 2/4 maven
example.DivTest
$ launchable split-subset --subset-id subset/397825 --bin 1/2 maven
example.MulTest
example.AddTest
$ launchable split-subset --subset-id subset/397825 --bin 2/2 maven
example.DivTest
example.SubTest
ちなみに、デフォルトではテスト実行時間が均等になるように分割されます。
GitHub Actions での例
Day 12の設定を元に4並列でテストを実行するように設定します。
primary-nodeで --split
オプションを使用し launchable subset
を実行。出力されたSubset IDをworker-node1から4へ渡します。
worker-node1から4では渡されたSubset IDを使用し launchable split-subset
で4つに分割したPTSの結果をそれぞれ取得しテストを実行。その後結果をレポート。
という流れになっています。
primary-node:
runs-on: ubuntu-latest
outputs:
- test_session: ${{ steps.issue_test_session.outputs.test_session}}
+ subset_id: ${{ steps.issue_subset_id.outputs.subset_id}}
steps:
- uses: actions/checkout@v3
with:
...
run: launchable verify
- name: record build
run: launchable record build --name ${GITHUB_RUN_ID}
- - name: record session
- id: issue_test_session
+ - name: subset
+ id: issue_subset_id
run: |
- launchable record session --build ${GITHUB_RUN_ID} > test_session.txt
- test_session=$(cat test_session.txt)
- echo "test_session=$test_session" >> $GITHUB_OUTPUT
- worker-node:
+ launchable subset --target 100% --split maven src/test/java > launchable-subset-id.txt
+ subset_id=$(cat launchable-subset-id.txt)
+ echo "subset_id=$subset_id" >> $GITHUB_OUTPUT
+ worker-node1:
runs-on: ubuntu-latest
needs: [primary-node]
steps:
...
- uses: actions/setup-python@v4 [35/12654]
with:
python-version: "3.10"
- - name: Set up JDK 1.8
- uses: actions/setup-java@v3
+ - name: Install launchable command
+ run: |
+ pip install launchable
+ - name: Restore subset-id
+ run: echo -n '${{needs.primary-node.outputs.subset_id}}' > launchable-subset-id.txt
+ - name: split subset
+ run: launchable split-subset --subset-id $(cat launchable-subset-id.txt) --bin 1/4 maven > launchable-subset.txt
+ - name: Run tests
+ run: mvn test -Dsurefire.includesFile=launchable-subset.txt
+ - name: launchable record tests
+ run: launchable record tests --subset-id $(cat launchable-subset-id.txt) maven target/surefire-reports/TEST-example.*.xml
+ if: always()
+ worker-node2:
+ runs-on: ubuntu-latest
+ needs: [primary-node]
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v4
with:
- distribution: 'adopt'
- java-version: '8'
+ python-version: "3.10"
- name: Install launchable command
run: |
pip install launchable
- - name: Restore test session
- run: echo -n '${{needs.primary-node.outputs.test_session}}' > test_session.txt
- - name: subset
- run: launchable subset --session $(cat test_session.txt) --target 80% maven src/test/java > launchable-subset.txt
+ - name: Restore subset-id
+ run: echo -n '${{needs.primary-node.outputs.subset_id}}' > launchable-subset-id.txt
+ - name: split subset
+ run: launchable split-subset --subset-id $(cat launchable-subset-id.txt) --bin 2/4 maven > launchable-subset.txt
+ - name: Run tests
+ run: mvn test -Dsurefire.includesFile=launchable-subset.txt
+ - name: launchable record tests
+ run: launchable record tests --subset-id $(cat launchable-subset-id.txt) maven target/surefire-reports/TEST-example.*.xml
+ if: always()
+ worker-node3:
+ runs-on: ubuntu-latest
+ needs: [primary-node]
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v4
+ with:
+ python-version: "3.10"
+ - name: Install launchable command
+ run: |
+ pip install launchable
+ - name: Restore subset-id
+ run: echo -n '${{needs.primary-node.outputs.subset_id}}' > launchable-subset-id.txt
+ - name: split subset
+ run: launchable split-subset --subset-id $(cat launchable-subset-id.txt) --bin 3/4 maven > launchable-subset.txt
+ - name: Run tests
+ run: mvn test -Dsurefire.includesFile=launchable-subset.txt
+ - name: launchable record tests
+ run: launchable record tests --subset-id $(cat launchable-subset-id.txt) maven target/surefire-reports/TEST-example.*.xml
+ if: always()
+ worker-node4:
+ runs-on: ubuntu-latest
+ needs: [primary-node]
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v4
+ with:
+ python-version: "3.10"
+ - name: Install launchable command
+ run: |
+ pip install launchable
+ - name: Restore subset-id
+ run: echo -n '${{needs.primary-node.outputs.subset_id}}' > launchable-subset-id.txt
+ - name: split subset
+ run: launchable split-subset --subset-id $(cat launchable-subset-id.txt) --bin 4/4 maven > launchable-subset.txt
- name: Run tests
run: mvn test -Dsurefire.includesFile=launchable-subset.txt
- name: launchable record tests
- run: launchable record tests --session $(cat test_session.txt) maven target/surefire-reports/TEST-example.*.xml
+ run: launchable record tests --subset-id $(cat launchable-subset-id.txt) maven target/surefire-reports/TEST-example.*.xml
if: always()
問題なく設定しテストを実行するとこのようになります。
さいごに
本日は並列でテストを実行するSplit Subsetについて紹介しました。
明日はSplit Subsetのオプションである include
/exclude
オプションについて紹介します。
Discussion