mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Add fail fast to test runner.
Passing `--fail-fast` to the test runner will now abort the test run on the first failure. The run continues on any unexpected errors.
This commit is contained in:
parent
64a3b09b40
commit
2310fb9d81
5 changed files with 84 additions and 0 deletions
|
@ -1,3 +1,35 @@
|
||||||
|
* Add fail fast to `bin/rails test`
|
||||||
|
|
||||||
|
Adding `--fail-fast` or `-f` when running tests will interrupt the run on
|
||||||
|
the first failure:
|
||||||
|
|
||||||
|
```
|
||||||
|
# Running:
|
||||||
|
|
||||||
|
................................................S......E
|
||||||
|
|
||||||
|
ArgumentError: Wups! Bet you didn't expect this!
|
||||||
|
test/models/bunny_test.rb:19:in `block in <class:BunnyTest>'
|
||||||
|
|
||||||
|
bin/rails test test/models/bunny_test.rb:18
|
||||||
|
|
||||||
|
....................................F
|
||||||
|
|
||||||
|
This failed
|
||||||
|
|
||||||
|
bin/rails test test/models/bunny_test.rb:14
|
||||||
|
|
||||||
|
Interrupted. Exiting...
|
||||||
|
|
||||||
|
|
||||||
|
Finished in 0.051427s, 1808.3872 runs/s, 1769.4972 assertions/s.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that any unexpected errors don't abort the run.
|
||||||
|
|
||||||
|
*Kasper Timm Hansen*
|
||||||
|
|
||||||
* Add inline output to `bin/rails test`
|
* Add inline output to `bin/rails test`
|
||||||
|
|
||||||
Any failures or errors (and skips if running in verbose mode) are output
|
Any failures or errors (and skips if running in verbose mode) are output
|
||||||
|
|
|
@ -33,6 +33,11 @@ module Minitest
|
||||||
options[:output_inline] = false
|
options[:output_inline] = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
opts.on("-f", "--fail-fast",
|
||||||
|
"Abort test run on first failure") do
|
||||||
|
options[:fail_fast] = true
|
||||||
|
end
|
||||||
|
|
||||||
options[:patterns] = opts.order!
|
options[:patterns] = opts.order!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,10 @@ module Rails
|
||||||
io.puts format_rerun_snippet(result)
|
io.puts format_rerun_snippet(result)
|
||||||
io.puts
|
io.puts
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if fail_fast? && result.failure && !result.error? && !result.skipped?
|
||||||
|
raise Interrupt
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def report
|
def report
|
||||||
|
@ -48,6 +52,10 @@ module Rails
|
||||||
options.fetch(:output_inline, true)
|
options.fetch(:output_inline, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def fail_fast?
|
||||||
|
options[:fail_fast]
|
||||||
|
end
|
||||||
|
|
||||||
def format_rerun_snippet(result)
|
def format_rerun_snippet(result)
|
||||||
location, line = result.method(result.name).source_location
|
location, line = result.method(result.name).source_location
|
||||||
"#{self.executable} #{relative_path_for(location)}:#{line}"
|
"#{self.executable} #{relative_path_for(location)}:#{line}"
|
||||||
|
|
|
@ -355,6 +355,21 @@ module ApplicationTests
|
||||||
assert_match %r{Running:\n\nF\n\nwups!\n\nbin/rails test test/models/post_test.rb:4}, output
|
assert_match %r{Running:\n\nF\n\nwups!\n\nbin/rails test test/models/post_test.rb:4}, output
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_fail_fast
|
||||||
|
app_file 'test/models/post_test.rb', <<-RUBY
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class PostTest < ActiveSupport::TestCase
|
||||||
|
def test_post
|
||||||
|
assert false, 'wups!'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
RUBY
|
||||||
|
|
||||||
|
assert_match(/Interrupt/,
|
||||||
|
capture(:stderr) { run_test_command('test/models/post_test.rb --fail-fast') })
|
||||||
|
end
|
||||||
|
|
||||||
def test_raise_error_when_specified_file_does_not_exist
|
def test_raise_error_when_specified_file_does_not_exist
|
||||||
error = capture(:stderr) { run_test_command('test/not_exists.rb') }
|
error = capture(:stderr) { run_test_command('test/not_exists.rb') }
|
||||||
assert_match(%r{cannot load such file.+test/not_exists\.rb}, error)
|
assert_match(%r{cannot load such file.+test/not_exists\.rb}, error)
|
||||||
|
|
|
@ -86,6 +86,30 @@ class TestUnitReporterTest < ActiveSupport::TestCase
|
||||||
assert_no_match 'Failed tests:', @output.string
|
assert_no_match 'Failed tests:', @output.string
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "fail fast interrupts run on failure" do
|
||||||
|
fail_fast = Rails::TestUnitReporter.new @output, fail_fast: true
|
||||||
|
interrupt_raised = false
|
||||||
|
|
||||||
|
# Minitest passes through Interrupt, catch it manually.
|
||||||
|
begin
|
||||||
|
fail_fast.record(failed_test)
|
||||||
|
rescue Interrupt
|
||||||
|
interrupt_raised = true
|
||||||
|
ensure
|
||||||
|
assert interrupt_raised, 'Expected Interrupt to be raised.'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "fail fast does not interrupt run errors or skips" do
|
||||||
|
fail_fast = Rails::TestUnitReporter.new @output, fail_fast: true
|
||||||
|
|
||||||
|
fail_fast.record(errored_test)
|
||||||
|
assert_no_match 'Failed tests:', @output.string
|
||||||
|
|
||||||
|
fail_fast.record(skipped_test)
|
||||||
|
assert_no_match 'Failed tests:', @output.string
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def assert_rerun_snippet_count(snippet_count)
|
def assert_rerun_snippet_count(snippet_count)
|
||||||
assert_equal snippet_count, @output.string.scan(%r{^bin/rails test }).size
|
assert_equal snippet_count, @output.string.scan(%r{^bin/rails test }).size
|
||||||
|
|
Loading…
Reference in a new issue