1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Ensure test rake commands run immediately

Before this commit, Rails test Rake tasks only load the test files, and
the tests only run in an at_exit hook via minitest/autorun.

This prevents conditionally running tasks only when tests pass, or even
more simply in the right order. As a simple example, if you have:

task default: [:test, :rubocop]

The rubocop task will run after the test task loads the test files but
before the tests actually run.

This commit changes the test Rake tasks to shell out to the test runner
as a new process.

This diverges from previous behavior because now, any changes made in
the Rakefile or other code loaded by Rake won't be available to the
child process. However this brings the behavior of `rake test` closer to
the behavior of `rails test`.

Co-authored-by: Adrianna Chang <adrianna.chang@shopify.com>
This commit is contained in:
Étienne Barrié 2021-01-15 15:52:32 -05:00
parent f250208dd4
commit 9aac3cb1d2
3 changed files with 26 additions and 12 deletions

View file

@ -30,9 +30,9 @@ module Rails
end end
def rake_run(argv = []) def rake_run(argv = [])
ARGV.replace Shellwords.split(ENV["TESTOPTS"] || "") # Ensure the tests run during the Rake Task action, not when the process exits
success = system("rails", "test", *argv, *Shellwords.split(ENV["TESTOPTS"] || ""))
run(argv) success || exit(false)
end end
def run(argv = []) def run(argv = [])

View file

@ -8,8 +8,6 @@ task default: :test
desc "Runs all tests in test folder except system ones" desc "Runs all tests in test folder except system ones"
task :test do task :test do
$: << "test"
if ENV.key?("TEST") if ENV.key?("TEST")
Rails::TestUnit::Runner.rake_run([ENV["TEST"]]) Rails::TestUnit::Runner.rake_run([ENV["TEST"]])
else else
@ -30,35 +28,29 @@ namespace :test do
["models", "helpers", "channels", "controllers", "mailers", "integration", "jobs", "mailboxes"].each do |name| ["models", "helpers", "channels", "controllers", "mailers", "integration", "jobs", "mailboxes"].each do |name|
task name => "test:prepare" do task name => "test:prepare" do
$: << "test"
Rails::TestUnit::Runner.rake_run(["test/#{name}"]) Rails::TestUnit::Runner.rake_run(["test/#{name}"])
end end
end end
desc "Runs all tests, including system tests" desc "Runs all tests, including system tests"
task all: "test:prepare" do task all: "test:prepare" do
$: << "test"
Rails::TestUnit::Runner.rake_run(["test/**/*_test.rb"]) Rails::TestUnit::Runner.rake_run(["test/**/*_test.rb"])
end end
task generators: "test:prepare" do task generators: "test:prepare" do
$: << "test"
Rails::TestUnit::Runner.rake_run(["test/lib/generators"]) Rails::TestUnit::Runner.rake_run(["test/lib/generators"])
end end
task units: "test:prepare" do task units: "test:prepare" do
$: << "test"
Rails::TestUnit::Runner.rake_run(["test/models", "test/helpers", "test/unit"]) Rails::TestUnit::Runner.rake_run(["test/models", "test/helpers", "test/unit"])
end end
task functionals: "test:prepare" do task functionals: "test:prepare" do
$: << "test"
Rails::TestUnit::Runner.rake_run(["test/controllers", "test/mailers", "test/functional"]) Rails::TestUnit::Runner.rake_run(["test/controllers", "test/mailers", "test/functional"])
end end
desc "Run system tests only" desc "Run system tests only"
task system: "test:prepare" do task system: "test:prepare" do
$: << "test"
Rails::TestUnit::Runner.rake_run(["test/system"]) Rails::TestUnit::Runner.rake_run(["test/system"])
end end
end end

View file

@ -686,7 +686,7 @@ module ApplicationTests
def test_rake_passes_TESTOPTS_to_minitest def test_rake_passes_TESTOPTS_to_minitest
create_test_file :models, "account" create_test_file :models, "account"
output = Dir.chdir(app_path) { `bin/rake test TESTOPTS=-v` } output = Dir.chdir(app_path) { `bin/rake test TESTOPTS=-v` }
assert_match "AccountTest#test_truth", output, "passing TEST= should run selected test" assert_match "AccountTest#test_truth", output, "passing TESTOPTS= should be sent to the test runner"
end end
def test_running_with_ruby_gets_test_env_by_default def test_running_with_ruby_gets_test_env_by_default
@ -745,6 +745,28 @@ module ApplicationTests
assert_match "ar_internal_metadata", output assert_match "ar_internal_metadata", output
end end
def test_rake_runs_tests_before_other_tasks_when_specified
app_file "Rakefile", <<~RUBY, "a"
task :echo do
puts "echo"
end
RUBY
output = Dir.chdir(app_path) { `bin/rake test echo` }
assert_equal "echo", output.split("\n").last
end
def test_rake_exits_on_failure
create_test_file :models, "post", pass: false
app_file "Rakefile", <<~RUBY, "a"
task :echo do
puts "echo"
end
RUBY
output = Dir.chdir(app_path) { `bin/rake test echo` }
assert_no_match "echo", output
assert_not_predicate $?, :success?
end
def test_warnings_option def test_warnings_option
app_file "test/models/warnings_test.rb", <<-RUBY app_file "test/models/warnings_test.rb", <<-RUBY
require "test_helper" require "test_helper"