Skip to content

テスト: 全体テストを pytest-xdist で並列実行する(順に 3 分 20 秒 → 並列 37 秒) #882

Description

@takemi-ohama

何を見つけたか

全体テストを 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)。

直し方

  1. 継続的統合・PR テンプレート・CONTRIBUTING.md のコマンドへ -n auto を足す。--project を使わない形では --with pytest-xdist も足す

  2. 並列で落ちるテストを先に洗い出す。 手元では 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 へ寄せる

  3. 根の conftest.py の前提(git の全体設定・NDF_METRICS_DIR・MONITOR_* の除去)が worker ごとに効くことを確かめる(手元の 3 回では効いている)

  4. 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

  • 要求と受け入れ条件 — 2026-09-23 05:37
  • 作業場所の用意 — 2026-09-23 05:38
  • 設計
  • 素材の収集と出典の確定
  • ドキュメント再構成
  • ドキュメントレビュー
  • 計画
  • 実装 — 2026-09-23 05:40
  • 構造改善
  • 実装レビュー — 2026-09-23 05:59
  • 完了判定 — 2026-09-23 06:13
  • Pull Request — 2026-09-23 05:50
  • 確定仕様化
  • 後片付け — 2026-09-23 06:15
  • 配布 — 2026-09-23 06:16
  • 体裁レビュー
  • リリース後テスト
  • 振り返り

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: ci継続的統合とワークフローenhancementNew feature or requestpriority: high実害・安全機構の欠落など、優先して対応する

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions