diff --git a/Lib/test/test_unittest.py b/Lib/test/test_unittest.py index df656e4..ed5dfcd 100644 --- a/Lib/test/test_unittest.py +++ b/Lib/test/test_unittest.py @@ -2124,6 +2124,61 @@ class Test_TestCase(TestCase, TestEquality, TestHashing): 'stopTest'] self.assertEqual(events, expected) + # "When a setUp() method is defined, the test runner will run that method + # prior to each test. Likewise, if a tearDown() method is defined, the + # test runner will invoke that method after each test. In the example, + # setUp() was used to create a fresh sequence for each test." + # + # Make sure the proper call order is maintained, even if tearDown() raises + # a failure exception. + def test_run_call_order__failure_in_tearDown(self): + events = [] + result = LoggingResult(events) + + class Foo(unittest.TestCase): + def setUp(self): + events.append('setUp') + + def test(self): + events.append('test') + + def tearDown(self): + events.append('tearDown') + raise AssertionError('raised by Foo.tearDown') + + Foo('test').run(result) + expected = ['startTest', 'setUp', 'test', 'tearDown', 'addFailure', + 'stopTest'] + self.assertEqual(events, expected) + + # "When a setUp() method is defined, the test runner will run that method + # prior to each test. Likewise, if a tearDown() method is defined, the + # test runner will invoke that method after each test. In the example, + # setUp() was used to create a fresh sequence for each test." + # + # Make sure the only event registered is a failure, even though both + # test and tearDown methods raise a failure exception. + def test_run_call_order__failure_in_tearDown_after_failure_in_test(self): + events = [] + result = LoggingResult(events) + + class Foo(unittest.TestCase): + def setUp(self): + events.append('setUp') + + def test(self): + events.append('test') + raise AssertionError('raised by Foo.test') + + def tearDown(self): + events.append('tearDown') + raise AssertionError('raised by Foo.tearDown') + + Foo('test').run(result) + expected = ['startTest', 'setUp', 'test', 'addFailure', 'tearDown', + 'stopTest'] + self.assertEqual(events, expected) + # "This class attribute gives the exception raised by the test() method. # If a test framework needs to use a specialized exception, possibly to # carry additional information, it must subclass this exception in diff --git a/Lib/unittest.py b/Lib/unittest.py index ccce746..48312e4 100644 --- a/Lib/unittest.py +++ b/Lib/unittest.py @@ -289,6 +289,10 @@ class TestCase(object): try: self.tearDown() + except self.failureException: + if ok: + result.addFailure(self, self._exc_info()) + ok = False except Exception: result.addError(self, self._exc_info()) ok = False