isolated テストタスクの廃止による CI シンプル化

rails/rails

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 が除かれ、testtest: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.mdrake test の説明から「non-isolated」という限定表現が削除され、guides/source/contributing_to_ruby_on_rails.md からは isolated タスクの使用例と「activestorage は非対応」という注記が削除されています。

設計判断

コスト対効果の評価に基づいてテスト手法ごとタスクを廃止するという判断が採られました。

isolated テストをメンテナンスし続ける選択肢として、buildkite-config#177 の議論では megatest への移植も検討されましたが、「有用性そのものが疑わしい」として却下されています。CI から外すだけでなくタスク定義ごと削除することで、将来的な誤使用や「なぜ CI で動いていないのか」という混乱を防ぐ意図が読み取れます。

また、activestorageabort により明示的にエラーを返していた特殊ケースも、タスク自体の削除によって自然に解消されています。例外処理を個別に維持するよりも、対象を統一して削除する方がコードベースの一貫性を高めるという判断といえます。

まとめ

isolated テストタスクの廃止は、CI での停止(buildkite-config 側)とリポジトリのタスク定義削除(本 PR)の2段階で完結しました。実行速度と検出価値のトレードオフを再評価した結果、複雑な並列プロセス実行の仕組みを維持するよりも削除を選ぶという、メンテナビリティ優先の判断が示されています。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
43bac55a

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
リトライ後承認
Review Count:
2回 (改善を経て承認)
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

「総論→各論→結論」の構成が明確です。リード文、背景、技術詳細、設計判断、まとめがすべて含まれており、理想的な構成です。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライトやGitHub PRへのリンク記法が正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

Railsの内部構造に関する変更を扱っており、専門知識を持つエンジニアという対象読者に適合した内容です。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論→各論の構成になっており、各段落もトピックセンテンスで始まるなど、パラグラフ・ライティングの原則が守られています。非常に読みやすいです。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内で引用されているRakefileのコードは、提供されたDiffと完全に一致しています。また、activerecord/Rakefileの削除行数やドキュメントの変更内容に関する説明も正確です。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「isolated テスト」「サブプロセス」「定数汚染」など、文脈に合った正確な技術用語が使用されています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

isolatedテストの仕組みや廃止の経緯に関する説明は、DiffやPRの情報と整合性が取れており、技術的に正確です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事内の主張はすべてPRのDescription、Diff、またはリンク先のPRで裏付けられています。「megatestへの移植検討」などの詳細な記述も、関連情報に基づいており、ハルシネーションは見られません。

数値・固有名詞の確認 ⚠ WARNING

PR番号・コミットID・バージョン等の正確性

「合わせて12ファイルが変更されました」との記述がありますが、提供されたDiff情報を元に数えると14ファイル(Rakefile, AGENTS.md, guides/..., 11のフレームワークRakefile)が変更されており、数値に軽微な誤りがあります。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事タイトル「isolated テストタスクの廃止による CI シンプル化」は、PRの「Remove isolated test tasks」という内容を的確に要約し、その影響まで示唆しており、優れています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事はPRで提供された情報(リンク先を含む)の範囲内で記述されており、無関係な外部知識(バージョンサポート状況など)の持ち込みはありません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

先行PR(...がすでに行われており)と本PR(...はその続行として)の時間的な前後関係が正確に表現されています。