Skip to content

Commit 9aac3cb

Browse files
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 <[email protected]>
1 parent f250208 commit 9aac3cb

File tree

3 files changed

+26
-12
lines changed

3 files changed

+26
-12
lines changed

railties/lib/rails/test_unit/runner.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ def parse_options(argv)
3030
end
3131

3232
def rake_run(argv = [])
33-
ARGV.replace Shellwords.split(ENV["TESTOPTS"] || "")
34-
35-
run(argv)
33+
# Ensure the tests run during the Rake Task action, not when the process exits
34+
success = system("rails", "test", *argv, *Shellwords.split(ENV["TESTOPTS"] || ""))
35+
success || exit(false)
3636
end
3737

3838
def run(argv = [])

railties/lib/rails/test_unit/testing.rake

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ task default: :test
88

99
desc "Runs all tests in test folder except system ones"
1010
task :test do
11-
$: << "test"
12-
1311
if ENV.key?("TEST")
1412
Rails::TestUnit::Runner.rake_run([ENV["TEST"]])
1513
else
@@ -30,35 +28,29 @@ namespace :test do
3028

3129
["models", "helpers", "channels", "controllers", "mailers", "integration", "jobs", "mailboxes"].each do |name|
3230
task name => "test:prepare" do
33-
$: << "test"
3431
Rails::TestUnit::Runner.rake_run(["test/#{name}"])
3532
end
3633
end
3734

3835
desc "Runs all tests, including system tests"
3936
task all: "test:prepare" do
40-
$: << "test"
4137
Rails::TestUnit::Runner.rake_run(["test/**/*_test.rb"])
4238
end
4339

4440
task generators: "test:prepare" do
45-
$: << "test"
4641
Rails::TestUnit::Runner.rake_run(["test/lib/generators"])
4742
end
4843

4944
task units: "test:prepare" do
50-
$: << "test"
5145
Rails::TestUnit::Runner.rake_run(["test/models", "test/helpers", "test/unit"])
5246
end
5347

5448
task functionals: "test:prepare" do
55-
$: << "test"
5649
Rails::TestUnit::Runner.rake_run(["test/controllers", "test/mailers", "test/functional"])
5750
end
5851

5952
desc "Run system tests only"
6053
task system: "test:prepare" do
61-
$: << "test"
6254
Rails::TestUnit::Runner.rake_run(["test/system"])
6355
end
6456
end

railties/test/application/test_runner_test.rb

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ def test_rails_db_create_all_restores_db_connection_after_drop
686686
def test_rake_passes_TESTOPTS_to_minitest
687687
create_test_file :models, "account"
688688
output = Dir.chdir(app_path) { `bin/rake test TESTOPTS=-v` }
689-
assert_match "AccountTest#test_truth", output, "passing TEST= should run selected test"
689+
assert_match "AccountTest#test_truth", output, "passing TESTOPTS= should be sent to the test runner"
690690
end
691691

692692
def test_running_with_ruby_gets_test_env_by_default
@@ -745,6 +745,28 @@ def test_rake_db_and_test_tasks_parses_args_correctly
745745
assert_match "ar_internal_metadata", output
746746
end
747747

748+
def test_rake_runs_tests_before_other_tasks_when_specified
749+
app_file "Rakefile", <<~RUBY, "a"
750+
task :echo do
751+
puts "echo"
752+
end
753+
RUBY
754+
output = Dir.chdir(app_path) { `bin/rake test echo` }
755+
assert_equal "echo", output.split("\n").last
756+
end
757+
758+
def test_rake_exits_on_failure
759+
create_test_file :models, "post", pass: false
760+
app_file "Rakefile", <<~RUBY, "a"
761+
task :echo do
762+
puts "echo"
763+
end
764+
RUBY
765+
output = Dir.chdir(app_path) { `bin/rake test echo` }
766+
assert_no_match "echo", output
767+
assert_not_predicate $?, :success?
768+
end
769+
748770
def test_warnings_option
749771
app_file "test/models/warnings_test.rb", <<-RUBY
750772
require "test_helper"

0 commit comments

Comments
 (0)