Skip to content

Commit b057fab

Browse files
committed
Exceptions like Interrupt should not be rescued.
Neither Test::Unit nor MiniTest rescue exceptions like Interrupt or NoMemoryError, but ActiveSupport::Testing::SetupAndTeardown#run which overrides MiniTest::Unit::TestCase#run rescues them. Rescuing an Interrupt exception is annoying, because it means when you are running a lot of tests e.g. when running one of the rake test tasks, you cannot break out using ctrl-C. Rescuing exceptions like NoMemoryError is foolish, because the most sensible thing to happen is for the process to terminate as soon as possible. This solution probably needs some finessing e.g. I'm not clear whether the assumption is that only MiniTest is supported. Also early versions of MiniTest did not have this behaviour. However, hopefully it's a start. Integrating with Test::Unit & MiniTest has always been a pain. It would be great if both of them provided sensible extension points for the kind of things that both Rails and Mocha want to do.
1 parent f5e26bc commit b057fab

File tree

2 files changed

+54
-8
lines changed

2 files changed

+54
-8
lines changed

activesupport/lib/active_support/testing/setup_and_teardown.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,15 @@ def run(runner)
2828
run_callbacks :setup do
2929
result = super
3030
end
31+
rescue *::MiniTest::Unit::TestCase::PASSTHROUGH_EXCEPTIONS
32+
raise
3133
rescue Exception => e
3234
result = runner.puke(self.class, method_name, e)
3335
ensure
3436
begin
3537
run_callbacks :teardown
38+
rescue *::MiniTest::Unit::TestCase::PASSTHROUGH_EXCEPTIONS
39+
raise
3640
rescue Exception => e
3741
result = runner.puke(self.class, method_name, e)
3842
end

activesupport/test/test_case_test.rb

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,9 @@ def options
1818
end
1919
end
2020

21-
def test_callback_with_exception
21+
def test_standard_error_raised_within_setup_callback_is_puked
2222
tc = Class.new(TestCase) do
23-
def self.name
24-
nil
25-
end
23+
def self.name; nil; end
2624

2725
setup :bad_callback
2826
def bad_callback; raise 'oh noes' end
@@ -41,11 +39,9 @@ def test_true; assert true end
4139
assert_equal 'oh noes', exception.message
4240
end
4341

44-
def test_teardown_callback_with_exception
42+
def test_standard_error_raised_within_teardown_callback_is_puked
4543
tc = Class.new(TestCase) do
46-
def self.name
47-
nil
48-
end
44+
def self.name; nil; end
4945

5046
teardown :bad_callback
5147
def bad_callback; raise 'oh noes' end
@@ -63,5 +59,51 @@ def test_true; assert true end
6359
assert_equal test_name, name
6460
assert_equal 'oh noes', exception.message
6561
end
62+
63+
def test_passthrough_exception_raised_within_test_method_is_not_rescued
64+
tc = Class.new(TestCase) do
65+
def self.name; nil; end
66+
67+
def test_which_raises_interrupt; raise Interrupt; end
68+
end
69+
70+
test_name = 'test_which_raises_interrupt'
71+
fr = FakeRunner.new
72+
73+
test = tc.new test_name
74+
assert_raises(Interrupt) { test.run fr }
75+
end
76+
77+
def test_passthrough_exception_raised_within_setup_callback_is_not_rescued
78+
tc = Class.new(TestCase) do
79+
def self.name; nil; end
80+
81+
setup :callback_which_raises_interrupt
82+
def callback_which_raises_interrupt; raise Interrupt; end
83+
def test_true; assert true end
84+
end
85+
86+
test_name = 'test_true'
87+
fr = FakeRunner.new
88+
89+
test = tc.new test_name
90+
assert_raises(Interrupt) { test.run fr }
91+
end
92+
93+
def test_passthrough_exception_raised_within_teardown_callback_is_not_rescued
94+
tc = Class.new(TestCase) do
95+
def self.name; nil; end
96+
97+
teardown :callback_which_raises_interrupt
98+
def callback_which_raises_interrupt; raise Interrupt; end
99+
def test_true; assert true end
100+
end
101+
102+
test_name = 'test_true'
103+
fr = FakeRunner.new
104+
105+
test = tc.new test_name
106+
assert_raises(Interrupt) { test.run fr }
107+
end
66108
end
67109
end

0 commit comments

Comments
 (0)