mirror of
https://github.com/python/cpython.git
synced 2025-08-22 17:55:18 +00:00
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 08d9e597c8
)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
parent
243b8de0b1
commit
d65fad04fa
4 changed files with 719 additions and 70 deletions
|
@ -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 = []
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue