何を見つけたか
全体テストを 1 プロセスで順に回しているため、待ち時間がテストの件数と遅い数件の合計で決まっている。 pytest-xdist は既に plugins/playwright-kit/skills/playwright-kit-ops/pyproject.toml の依存に入っているのに、継続的統合も手順書も -n を渡していない。
計測は develop(25da1de1)、9 コア・負荷の無い状態。
| 実行 |
件数 |
所要 |
uv run --project plugins/playwright-kit/skills/playwright-kit-ops --with pytest pytest . -q(現行) |
5337 |
3 分 20 秒 |
同じコマンドに -n 4 |
5337 |
60 秒 |
同じコマンドに -n auto |
5337 |
36〜37 秒(3 回とも全件合格) |
uv run --with pytest --with pytest-xdist pytest scripts/tests plugins/ndf -q -n auto |
5153 |
44 秒 |
負荷のある環境では 8 分を超える。 複数の作業ツリーや CLI を並行して動かしている最中の全体テストは 8 分以上かかっている(#880 では 1 項目あたり約 8 分)。順に回す限り、負荷の分だけそのまま伸びる。
どこで見つけたか
.github/workflows/pytest.yml:41
.github/pull_request_template.md:11
CONTRIBUTING.md:64
docs/specifications/ndf-worktree-declaration-and-entry-points.md:356、docs/specifications/test-monitor-env-isolation.md:59(uv run --with pytest pytest scripts/tests plugins/ndf -q)
- 利用者のメモリ・
quality-gates など、全体テストのコマンドを案内する箇所
直さないと何が起きるか
全体テストを回すたびに 3〜8 分待つ。cross-refactoring の --baseline-test のように全体テストを繰り返す工程では、待ちが回数倍になる(#880)。
直し方
-
継続的統合・PR テンプレート・CONTRIBUTING.md のコマンドへ -n auto を足す。--project を使わない形では --with pytest-xdist も足す
-
並列で落ちるテストを先に洗い出す。 手元では 3 回とも合格したが、ロックの競合を見るテスト(test_registry.py の test_many_at_once_*、test_lock_common.py の test_six_at_once_leave_one_owner など)は busy-wait で CPU を使うため、コア数の少ない runner で不安定になり得る。落ちるものがあれば xdist_group で 1 つの worker へ寄せる
-
根の conftest.py の前提(git の全体設定・NDF_METRICS_DIR・MONITOR_* の除去)が worker ごとに効くことを確かめる(手元の 3 回では効いている)
-
1 と 2 の後に CI で所要を測り、2 分を超えるならジョブを分割する(下の「ジョブの分割」)
ジョブの分割(段 2。1〜3 の後に要否を決める)
CI の pytest の内訳(PR #886、run 35821421926)は、準備 7 秒・テスト 5 分 30 秒である。 準備が軽いため、ジョブを分けたときの固定費はほぼ掛からない。public リポジトリなので runner の時間は費用にならない。
前例は /work/carmo-system-console の .github/workflows/laravel.yml にある。 形は次の 3 つで、このリポジトリでもそのまま使える。
| 前例の形 |
中身 |
このリポジトリでの扱い |
| matrix で N ジョブ |
strategy.matrix.job で分け、各ジョブが自分の分だけを実行する |
各ジョブの中は -n auto(4 vCPU)。N は 2〜3 から測って決める |
| 実測時間で分ける |
scripts/ci/balance-test-shards.php が前回の junit XML から LPT 貪欲法で割り当て、実測が無ければファイル名の剰余へ戻る |
最初はファイル名の剰余だけにする(根の conftest.py の pytest_collection_modifyitems で SHARD_INDEX / SHARD_TOTAL を読む)。偏りが出たら実測時間での割り当てへ進む |
| まとめジョブ |
test-results が needs で全ジョブを待ち、1 つの結果を返す |
まとめジョブの名前を pytest にする。 ruleset の必須の検査が pytest という名前を持つため、名前を変えると ruleset の変更(operation)が要る |
あわせて push の branches から "release/**" を外す(#884 に記録した 2 重実行)。runner の時間は減るが壁時計は縮まない。同時に走れるジョブ数の上限に対する余裕が空く。
受け入れ条件
- 継続的統合の pytest ジョブが
-n auto で走り、全件合格する
- 案内するコマンドがすべて並列の形になっている
ubuntu-latest での所要が、変更前のジョブ時間の半分以下になる
- 分割した場合も、ruleset の必須の検査
pytest が 1 つの結果として返り、ruleset を変えずにマージできる
関連
進行
モード: light / 作業ツリー: .worktrees/test/issue-882-884-test-speedup
何を見つけたか
全体テストを 1 プロセスで順に回しているため、待ち時間がテストの件数と遅い数件の合計で決まっている。
pytest-xdistは既にplugins/playwright-kit/skills/playwright-kit-ops/pyproject.tomlの依存に入っているのに、継続的統合も手順書も-nを渡していない。計測は
develop(25da1de1)、9 コア・負荷の無い状態。uv run --project plugins/playwright-kit/skills/playwright-kit-ops --with pytest pytest . -q(現行)-n 4-n autouv run --with pytest --with pytest-xdist pytest scripts/tests plugins/ndf -q -n auto負荷のある環境では 8 分を超える。 複数の作業ツリーや CLI を並行して動かしている最中の全体テストは 8 分以上かかっている(#880 では 1 項目あたり約 8 分)。順に回す限り、負荷の分だけそのまま伸びる。
どこで見つけたか
.github/workflows/pytest.yml:41.github/pull_request_template.md:11CONTRIBUTING.md:64docs/specifications/ndf-worktree-declaration-and-entry-points.md:356、docs/specifications/test-monitor-env-isolation.md:59(uv run --with pytest pytest scripts/tests plugins/ndf -q)quality-gatesなど、全体テストのコマンドを案内する箇所直さないと何が起きるか
全体テストを回すたびに 3〜8 分待つ。
cross-refactoringの--baseline-testのように全体テストを繰り返す工程では、待ちが回数倍になる(#880)。直し方
継続的統合・PR テンプレート・
CONTRIBUTING.mdのコマンドへ-n autoを足す。--projectを使わない形では--with pytest-xdistも足す並列で落ちるテストを先に洗い出す。 手元では 3 回とも合格したが、ロックの競合を見るテスト(
test_registry.pyのtest_many_at_once_*、test_lock_common.pyのtest_six_at_once_leave_one_ownerなど)は busy-wait で CPU を使うため、コア数の少ない runner で不安定になり得る。落ちるものがあればxdist_groupで 1 つの worker へ寄せる根の
conftest.pyの前提(git の全体設定・NDF_METRICS_DIR・MONITOR_*の除去)が worker ごとに効くことを確かめる(手元の 3 回では効いている)1 と 2 の後に CI で所要を測り、2 分を超えるならジョブを分割する(下の「ジョブの分割」)
ジョブの分割(段 2。1〜3 の後に要否を決める)
CI の pytest の内訳(PR #886、run 35821421926)は、準備 7 秒・テスト 5 分 30 秒である。 準備が軽いため、ジョブを分けたときの固定費はほぼ掛からない。public リポジトリなので runner の時間は費用にならない。
前例は
/work/carmo-system-consoleの.github/workflows/laravel.ymlにある。 形は次の 3 つで、このリポジトリでもそのまま使える。strategy.matrix.jobで分け、各ジョブが自分の分だけを実行する-n auto(4 vCPU)。N は 2〜3 から測って決めるscripts/ci/balance-test-shards.phpが前回の junit XML から LPT 貪欲法で割り当て、実測が無ければファイル名の剰余へ戻るconftest.pyのpytest_collection_modifyitemsでSHARD_INDEX/SHARD_TOTALを読む)。偏りが出たら実測時間での割り当てへ進むtest-resultsがneedsで全ジョブを待ち、1 つの結果を返すpytestにする。 ruleset の必須の検査がpytestという名前を持つため、名前を変えると ruleset の変更(operation)が要るあわせて push の
branchesから"release/**"を外す(#884 に記録した 2 重実行)。runner の時間は減るが壁時計は縮まない。同時に走れるジョブ数の上限に対する余裕が空く。受け入れ条件
-n autoで走り、全件合格するubuntu-latestでの所要が、変更前のジョブ時間の半分以下になるpytestが 1 つの結果として返り、ruleset を変えずにマージできる関連
進行
モード: light / 作業ツリー:
.worktrees/test/issue-882-884-test-speedup