CIテストのフレーク対策: `sleep 0.1` でステップ実行時間を調整
CI の並列実行テスト ContinuousIntegrationTest#test_parallel_group_stops_launching_new_steps_with_*_flag が、--fail-fast と -f の両フラグで間欠的に失敗していた問題を、ステップ実行時間を意図的に遅延させることで安定化した。
背景
このテストは parallel: 2 のグループ内で最初に失敗したステップ (Fail) が出た後、残りのステップが実行されないことを確認するものだが、従来の step "Should not run X", "true" は即時成功を返すため、スレッドが失敗を検知する前に次のステップがデキューされ、稀に「Should not run 3」が実行されテストがフレークした。
技術的な変更
テストコードの step 定義 を true から sleep 0.1 に置き換え、各ステップの実行時間を約 0.1 秒に延長した。これにより失敗ステップの完了 (false が約 0.02 秒で失敗) よりも後続ステップの実行が遅れ、ワーカーが失敗を認識した時点でキューからタスクが取り除かれ、期待どおりにスキップされるようになる。
@@ -311,9 +311,9 @@ class ContinuousIntegrationTest < ActiveSupport::TestCase
@CI.run("CI", nil) do
group "Checks", parallel: 2 do
step "Fail", "false"
- step "Should not run 1", "true"
- step "Should not run 2", "true"
- step "Should not run 3", "true"
+ step "Should not run 1", "sleep", "0.1"
+ step "Should not run 2", "sleep", "0.1"
+ step "Should not run 3", "sleep", "0.1"
end
end
end
設計判断
この修正は テストコードのみ に対する変更であり、実装ロジックや公開 API への影響はない。sleep を利用した遅延はテストの時間的特性を制御するシンプルな手段で、他のテストケースへの副作用を回避しつつフレークを除去できる点が採用された判断基準となっている。また、true ステップを残すと非決定的なスレッドスケジューリングに依存するため、明示的な遅延で deterministic にする方針が取られた。
まとめ
step "Should not run X" を sleep 0.1 に変更したことで、CI の並列テストにおける失敗後のステップスキップが確実になり、フレークが解消された。生産コードへの影響はなく、テストの信頼性向上という目的に特化した最小限の変更である。