summaryrefslogtreecommitdiffstats
path: root/Lib/unittest/test/test_runner.py
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2021-08-30 17:38:34 (GMT)
committerGitHub <noreply@github.com>2021-08-30 17:38:34 (GMT)
commitd65fad04fad1a73b6bb17bcb08ca6f0a24376952 (patch)
tree9e8ba8e47db04efe4a71be47780d2b9d256891f7 /Lib/unittest/test/test_runner.py
parent243b8de0b15061704581974c0a27db1232a43b93 (diff)
downloadcpython-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.py209
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 = []