isolated テストタスクの廃止による CI シンプル化
Rails の全フレームワークから test:isolated タスクが削除され、CI パイプラインとルート Rakefile が整理されました。実行コストに見合う検出効果が得られないと判断されたことが廃止の理由です。
背景
isolated テストとは、各テストファイルを独立したプロセス(Gem.ruby のサブプロセス)で1ファイルずつ実行し、他のファイルのロード状態に依存しない環境でテストを走らせる手法です。テスト間の副作用(定数汚染、自動ロードの干渉など)を検出できる一方で、プロセス起動のオーバーヘッドがファイル数だけ発生するため、通常のテスト実行より大幅に時間がかかります。
rails/buildkite-config#177 では isolated テストの CI 実行を停止する変更がすでに行われており、本 PR #57331 はその後続として、リポジトリ側のタスク定義自体を削除するものです。PR の説明では「実行が非常に遅く、検出できる問題も少ない。この複雑さを維持する価値はない」と明示されています。
なお、activestorage については isolated テストが定義されておらず、呼び出すと abort でエラー終了する特殊ケースが存在していました。このような例外処理も含め、タスク群全体が削除対象となっています。
技術的な変更
ルートの Rakefile と各フレームワークの Rakefile、合わせて12ファイルが変更されました。変更の核心はタスク定義の削除と、それに伴うデフォルトタスクの簡略化です。
ルート Rakefile では、default タスクの依存関係から test:isolated が除かれ、test と test:isolated を同一ループで生成していた構造がフラット化されました。
変更前:
task default: %w(test test:isolated)
%w(test test:isolated).each do |task_name|
desc "Run #{task_name} task for all projects"
task task_name do
errors = []
Releaser::FRAMEWORKS.each do |project|
system(%(cd #{project} && #{$0} #{task_name} --trace)) || errors << project
end
fail("Errors in #{errors.join(', ')}") unless errors.empty?
end
end
変更後:
task default: :test
desc "Run test task for all projects"
task "test" do
errors = []
Releaser::FRAMEWORKS.each do |project|
system(%(cd #{project} && #{$0} test --trace)) || errors << project
end
fail("Errors in #{errors.join(', ')}") unless errors.empty?
end
各フレームワークの Rakefile では namespace :test 内の isolated タスクが削除されました。たとえば activerecord/Rakefile では、アダプターごとのサブプロセス実行ロジック(-Ilib・-Itest の付与、Minitest.autorun の一時無効化、ファイル列挙と逐次実行)を含む約100行が削除されています。activejob/Rakefile でも namespace :isolated ブロックとアダプターごとのタスク定義が丸ごと除去されました。
ドキュメントも合わせて更新されており、AGENTS.md の rake test の説明から「non-isolated」という限定表現が削除され、guides/source/contributing_to_ruby_on_rails.md からは isolated タスクの使用例と「activestorage は非対応」という注記が削除されています。
設計判断
コスト対効果の評価に基づいてテスト手法ごとタスクを廃止するという判断が採られました。
isolated テストをメンテナンスし続ける選択肢として、buildkite-config#177 の議論では megatest への移植も検討されましたが、「有用性そのものが疑わしい」として却下されています。CI から外すだけでなくタスク定義ごと削除することで、将来的な誤使用や「なぜ CI で動いていないのか」という混乱を防ぐ意図が読み取れます。
また、activestorage で abort により明示的にエラーを返していた特殊ケースも、タスク自体の削除によって自然に解消されています。例外処理を個別に維持するよりも、対象を統一して削除する方がコードベースの一貫性を高めるという判断といえます。
まとめ
isolated テストタスクの廃止は、CI での停止(buildkite-config 側)とリポジトリのタスク定義削除(本 PR)の2段階で完結しました。実行速度と検出価値のトレードオフを再評価した結果、複雑な並列プロセス実行の仕組みを維持するよりも削除を選ぶという、メンテナビリティ優先の判断が示されています。