[Rails] テスト環境のENV汚染を徹底的にクリーンアップ
Context
Railsのテストスイートにおいて、ENV環境変数の変更が適切にクリーンアップされず、テスト間で状態が漏洩する問題が継続的に発生していました。この問題は#56563で報告され、特定のテスト実行順序で失敗が発生する原因となっていました。本PRは、この問題を根本的に解決するため、ENV変数の適切な管理とクリーンアップ処理を導入します。
Technical Detail
Rakeタスクでの ENV.delete パターンの導入
従来、Rakeタスクは ENV["FROM"] を直接参照していましたが、これがテスト後に環境変数を汚染していました。
変更前:
to_load = ENV["FROM"].blank? ? :all : ENV["FROM"].split(",").map(&:strip)
変更後:
from = ENV.delete("FROM")
to_load = from.blank? ? :all : from.split(",").map(&:strip)
ENV.delete を使用することで、値を取得すると同時に環境変数を削除し、後続のテストへの影響を防ぎます。
with_rails_env ヘルパーによるスコープ管理
複数のテストファイルで ENV["RAILS_ENV"] の直接代入が、with_rails_env ヘルパーを使ったスコープ管理に置き換えられました。
AssetDebuggingTestの改善:
test "assets are concatenated when debug is off and compile is off either if debug_assets param is provided" do
with_rails_env("production") do
rails "assets:precompile", "--trace"
app "production"
class ::PostsController < ActionController::Base ; end
get("/posts?debug_assets=true", {}, "HTTPS" => "on")
assert_match(/<script src="\/assets\/application-([0-z]+)\.js"><\/script>/, last_response.body)
end
end
このパターンにより、ブロック終了時に自動的に RAILS_ENV が元の状態に戻ります。ViewReloadingTest や ServerTest でも同様の改善が行われています。
restore_default_config による設定リセット
一部のテストでは、不要な build_app 呼び出しが restore_default_config に置き換えられました。
test "config.active_job.verbose_enqueue_logs defaults to true in development" do
restore_default_config
app "development"
assert ActiveJob.verbose_enqueue_logs
end
restore_default_config は既存のアプリケーション設定を再利用しつつ、環境変数をクリーンな状態に戻すため、テストの実行速度向上にも貢献します。
teardownでのENV削除処理の改善
teardown_app メソッドで、RAILS_ENV の復元処理が改善されました。
変更前:
def teardown_app
ENV["RAILS_ENV"] = @prev_rails_env if @prev_rails_env
# ...
end
変更後:
def teardown_app
if @prev_rails_env
ENV["RAILS_ENV"] = @prev_rails_env
else
ENV.delete("RAILS_ENV")
end
# ...
以前の実装では @prev_rails_env が nil の場合にENV変数が残留していましたが、明示的に delete することで確実にクリーンアップされます。
Generatorテストでの改善
ActionMailboxInstallGeneratorTest では、run_generator メソッドをオーバーライドして、with_database_configuration ブロック内で実行するように統一されました。
private
def run_generator
quietly { with_database_configuration { super } }
end
これにより、各テストケースで個別に with_database_configuration を呼び出す必要がなくなり、コードの重複が削減されました。
Impact
この変更により、Railsのテストスイート全体で環境変数の漏洩が防止され、テスト実行順序に依存する不安定なテスト失敗が解消されます。特に、CI環境での並列実行時の信頼性が大幅に向上します。