diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2021-08-30 17:38:34 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-30 17:38:34 (GMT) |
commit | d65fad04fad1a73b6bb17bcb08ca6f0a24376952 (patch) | |
tree | 9e8ba8e47db04efe4a71be47780d2b9d256891f7 /Lib/unittest/test/test_runner.py | |
parent | 243b8de0b15061704581974c0a27db1232a43b93 (diff) | |
download | cpython-d65fad04fad1a73b6bb17bcb08ca6f0a24376952.zip cpython-d65fad04fad1a73b6bb17bcb08ca6f0a24376952.tar.gz cpython-d65fad04fad1a73b6bb17bcb08ca6f0a24376952.tar.bz2 |
bpo-43913: Fix bugs in cleaning up classes and modules in unittest. (GH-28006)
* Functions registered with addModuleCleanup() were not called unless
the user defines tearDownModule() in their test module.
* Functions registered with addClassCleanup() were not called if
tearDownClass is set to None.
* Buffering in TestResult did not work with functions registered
with addClassCleanup() and addModuleCleanup().
* Errors in functions registered with addClassCleanup() and
addModuleCleanup() were not handled correctly in buffered and
debug modes.
* Errors in setUpModule() and functions registered with
addModuleCleanup() were reported in wrong order.
* And several lesser bugs.
(cherry picked from commit 08d9e597c8ef5a2b26375ac954fdf224f5d82c3c)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Diffstat (limited to 'Lib/unittest/test/test_runner.py')
-rw-r--r-- | Lib/unittest/test/test_runner.py | 209 |
1 files changed, 205 insertions, 4 deletions
diff --git a/Lib/unittest/test/test_runner.py b/Lib/unittest/test/test_runner.py index dd9a1b6..453e6c3 100644 --- a/Lib/unittest/test/test_runner.py +++ b/Lib/unittest/test/test_runner.py @@ -222,14 +222,42 @@ class TestClassCleanup(unittest.TestCase): self.assertEqual(ordering, ['setUpClass', 'test', 'tearDownClass', 'cleanup_good']) - def test_debug_executes_classCleanUp(self): + def test_run_class_cleanUp_without_tearDownClass(self): ordering = [] + blowUp = True class TestableTest(unittest.TestCase): @classmethod def setUpClass(cls): ordering.append('setUpClass') cls.addClassCleanup(cleanup, ordering) + if blowUp: + raise Exception() + def testNothing(self): + ordering.append('test') + @classmethod + @property + def tearDownClass(cls): + raise AttributeError + + runTests(TestableTest) + self.assertEqual(ordering, ['setUpClass', 'cleanup_good']) + + ordering = [] + blowUp = False + runTests(TestableTest) + self.assertEqual(ordering, + ['setUpClass', 'test', 'cleanup_good']) + + def test_debug_executes_classCleanUp(self): + ordering = [] + blowUp = False + + class TestableTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + ordering.append('setUpClass') + cls.addClassCleanup(cleanup, ordering, blowUp=blowUp) def testNothing(self): ordering.append('test') @classmethod @@ -241,6 +269,48 @@ class TestClassCleanup(unittest.TestCase): self.assertEqual(ordering, ['setUpClass', 'test', 'tearDownClass', 'cleanup_good']) + ordering = [] + blowUp = True + suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) + with self.assertRaises(Exception) as cm: + suite.debug() + self.assertEqual(str(cm.exception), 'CleanUpExc') + self.assertEqual(ordering, + ['setUpClass', 'test', 'tearDownClass', 'cleanup_exc']) + + def test_debug_executes_classCleanUp_when_teardown_exception(self): + ordering = [] + blowUp = False + + class TestableTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + ordering.append('setUpClass') + cls.addClassCleanup(cleanup, ordering, blowUp=blowUp) + def testNothing(self): + ordering.append('test') + @classmethod + def tearDownClass(cls): + raise Exception('TearDownClassExc') + + suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) + with self.assertRaises(Exception) as cm: + suite.debug() + self.assertEqual(str(cm.exception), 'TearDownClassExc') + self.assertEqual(ordering, ['setUpClass', 'test']) + self.assertTrue(TestableTest._class_cleanups) + TestableTest._class_cleanups.clear() + + ordering = [] + blowUp = True + suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) + with self.assertRaises(Exception) as cm: + suite.debug() + self.assertEqual(str(cm.exception), 'TearDownClassExc') + self.assertEqual(ordering, ['setUpClass', 'test']) + self.assertTrue(TestableTest._class_cleanups) + TestableTest._class_cleanups.clear() + def test_doClassCleanups_with_errors_addClassCleanUp(self): class TestableTest(unittest.TestCase): def testNothing(self): @@ -332,6 +402,7 @@ class TestClassCleanup(unittest.TestCase): self.assertEqual(ordering, ['setUpClass', 'setUp', 'test', 'tearDownClass', 'cleanup_exc']) + ordering = [] class_blow_up = True method_blow_up = False @@ -355,6 +426,26 @@ class TestClassCleanup(unittest.TestCase): ['setUpClass', 'setUp', 'tearDownClass', 'cleanup_exc']) + def test_with_errors_in_tearDownClass(self): + ordering = [] + class TestableTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + ordering.append('setUpClass') + cls.addClassCleanup(cleanup, ordering) + def testNothing(self): + ordering.append('test') + @classmethod + def tearDownClass(cls): + ordering.append('tearDownClass') + raise Exception('TearDownExc') + + result = runTests(TestableTest) + self.assertEqual(result.errors[0][1].splitlines()[-1], + 'Exception: TearDownExc') + self.assertEqual(ordering, + ['setUpClass', 'test', 'tearDownClass', 'cleanup_good']) + class TestModuleCleanUp(unittest.TestCase): def test_add_and_do_ModuleCleanup(self): @@ -532,13 +623,69 @@ class TestModuleCleanUp(unittest.TestCase): 'tearDownModule2', 'cleanup_good']) self.assertEqual(unittest.case._module_cleanups, []) - def test_debug_module_executes_cleanUp(self): + def test_run_module_cleanUp_without_teardown(self): ordering = [] class Module(object): @staticmethod def setUpModule(): ordering.append('setUpModule') unittest.addModuleCleanup(cleanup, ordering) + + class TestableTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + ordering.append('setUpClass') + def testNothing(self): + ordering.append('test') + @classmethod + def tearDownClass(cls): + ordering.append('tearDownClass') + + TestableTest.__module__ = 'Module' + sys.modules['Module'] = Module + runTests(TestableTest) + self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', + 'tearDownClass', 'cleanup_good']) + self.assertEqual(unittest.case._module_cleanups, []) + + def test_run_module_cleanUp_when_teardown_exception(self): + ordering = [] + class Module(object): + @staticmethod + def setUpModule(): + ordering.append('setUpModule') + unittest.addModuleCleanup(cleanup, ordering) + @staticmethod + def tearDownModule(): + raise Exception('CleanUpExc') + + class TestableTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + ordering.append('setUpClass') + def testNothing(self): + ordering.append('test') + @classmethod + def tearDownClass(cls): + ordering.append('tearDownClass') + + TestableTest.__module__ = 'Module' + sys.modules['Module'] = Module + result = runTests(TestableTest) + self.assertEqual(result.errors[0][1].splitlines()[-1], + 'Exception: CleanUpExc') + self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', + 'tearDownClass', 'cleanup_good']) + self.assertEqual(unittest.case._module_cleanups, []) + + def test_debug_module_executes_cleanUp(self): + ordering = [] + blowUp = False + class Module(object): + @staticmethod + def setUpModule(): + ordering.append('setUpModule') + unittest.addModuleCleanup(cleanup, ordering, blowUp=blowUp) @staticmethod def tearDownModule(): ordering.append('tearDownModule') @@ -562,6 +709,60 @@ class TestModuleCleanUp(unittest.TestCase): 'tearDownModule', 'cleanup_good']) self.assertEqual(unittest.case._module_cleanups, []) + ordering = [] + blowUp = True + suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) + with self.assertRaises(Exception) as cm: + suite.debug() + self.assertEqual(str(cm.exception), 'CleanUpExc') + self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', + 'tearDownClass', 'tearDownModule', 'cleanup_exc']) + self.assertEqual(unittest.case._module_cleanups, []) + + def test_debug_module_cleanUp_when_teardown_exception(self): + ordering = [] + blowUp = False + class Module(object): + @staticmethod + def setUpModule(): + ordering.append('setUpModule') + unittest.addModuleCleanup(cleanup, ordering, blowUp=blowUp) + @staticmethod + def tearDownModule(): + raise Exception('TearDownModuleExc') + + class TestableTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + ordering.append('setUpClass') + def testNothing(self): + ordering.append('test') + @classmethod + def tearDownClass(cls): + ordering.append('tearDownClass') + + TestableTest.__module__ = 'Module' + sys.modules['Module'] = Module + suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) + with self.assertRaises(Exception) as cm: + suite.debug() + self.assertEqual(str(cm.exception), 'TearDownModuleExc') + self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', + 'tearDownClass']) + self.assertTrue(unittest.case._module_cleanups) + unittest.case._module_cleanups.clear() + + ordering = [] + blowUp = True + suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) + with self.assertRaises(Exception) as cm: + suite.debug() + self.assertEqual(str(cm.exception), 'TearDownModuleExc') + self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', + 'tearDownClass']) + self.assertTrue(unittest.case._module_cleanups) + unittest.case._module_cleanups.clear() + def test_addClassCleanup_arg_errors(self): cleanups = [] def cleanup(*args, **kwargs): @@ -717,9 +918,9 @@ class TestModuleCleanUp(unittest.TestCase): method_blow_up = False result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: CleanUpExc') - self.assertEqual(result.errors[1][1].splitlines()[-1], 'Exception: ModuleExc') + self.assertEqual(result.errors[1][1].splitlines()[-1], + 'Exception: CleanUpExc') self.assertEqual(ordering, ['setUpModule', 'cleanup_exc']) ordering = [] |