bpo-24412: Adds cleanUps for setUpClass and setUpModule. (GH-9190)

This commit is contained in:
Lisa Roach 2018-11-08 18:34:33 -08:00 committed by GitHub
parent 49fa4a9f1e
commit 0f221d09ca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 783 additions and 18 deletions

View file

@ -11,8 +11,41 @@ from unittest.test.support import (LoggingResult,
ResultWithNoStartTestRunStopTestRun)
class TestCleanUp(unittest.TestCase):
def resultFactory(*_):
return unittest.TestResult()
def getRunner():
return unittest.TextTestRunner(resultclass=resultFactory,
stream=io.StringIO())
def runTests(*cases):
suite = unittest.TestSuite()
for case in cases:
tests = unittest.defaultTestLoader.loadTestsFromTestCase(case)
suite.addTests(tests)
runner = getRunner()
# creating a nested suite exposes some potential bugs
realSuite = unittest.TestSuite()
realSuite.addTest(suite)
# adding empty suites to the end exposes potential bugs
suite.addTest(unittest.TestSuite())
realSuite.addTest(unittest.TestSuite())
return runner.run(realSuite)
def cleanup(ordering, blowUp=False):
if not blowUp:
ordering.append('cleanup_good')
else:
ordering.append('cleanup_exc')
raise Exception('CleanUpExc')
class TestCleanUp(unittest.TestCase):
def testCleanUp(self):
class TestableTest(unittest.TestCase):
def testNothing(self):
@ -47,10 +80,10 @@ class TestCleanUp(unittest.TestCase):
test = TestableTest('testNothing')
outcome = test._outcome = _Outcome()
exc1 = Exception('foo')
CleanUpExc = Exception('foo')
exc2 = Exception('bar')
def cleanup1():
raise exc1
raise CleanUpExc
def cleanup2():
raise exc2
@ -63,7 +96,7 @@ class TestCleanUp(unittest.TestCase):
((_, (Type1, instance1, _)),
(_, (Type2, instance2, _))) = reversed(outcome.errors)
self.assertEqual((Type1, instance1), (Exception, exc1))
self.assertEqual((Type1, instance1), (Exception, CleanUpExc))
self.assertEqual((Type2, instance2), (Exception, exc2))
def testCleanupInRun(self):
@ -135,6 +168,575 @@ class TestCleanUp(unittest.TestCase):
self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup1', 'cleanup2'])
class TestClassCleanup(unittest.TestCase):
def test_addClassCleanUp(self):
class TestableTest(unittest.TestCase):
def testNothing(self):
pass
test = TestableTest('testNothing')
self.assertEqual(test._class_cleanups, [])
class_cleanups = []
def class_cleanup1(*args, **kwargs):
class_cleanups.append((3, args, kwargs))
def class_cleanup2(*args, **kwargs):
class_cleanups.append((4, args, kwargs))
TestableTest.addClassCleanup(class_cleanup1, 1, 2, 3,
four='hello', five='goodbye')
TestableTest.addClassCleanup(class_cleanup2)
self.assertEqual(test._class_cleanups,
[(class_cleanup1, (1, 2, 3),
dict(four='hello', five='goodbye')),
(class_cleanup2, (), {})])
TestableTest.doClassCleanups()
self.assertEqual(class_cleanups, [(4, (), {}), (3, (1, 2, 3),
dict(four='hello', five='goodbye'))])
def test_run_class_cleanUp(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
def tearDownClass(cls):
ordering.append('tearDownClass')
runTests(TestableTest)
self.assertEqual(ordering, ['setUpClass', 'cleanup_good'])
ordering = []
blowUp = False
runTests(TestableTest)
self.assertEqual(ordering,
['setUpClass', 'test', 'tearDownClass', 'cleanup_good'])
def test_debug_executes_classCleanUp(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')
suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest)
suite.debug()
self.assertEqual(ordering,
['setUpClass', 'test', 'tearDownClass', 'cleanup_good'])
def test_doClassCleanups_with_errors_addClassCleanUp(self):
class TestableTest(unittest.TestCase):
def testNothing(self):
pass
def cleanup1():
raise Exception('cleanup1')
def cleanup2():
raise Exception('cleanup2')
TestableTest.addClassCleanup(cleanup1)
TestableTest.addClassCleanup(cleanup2)
with self.assertRaises(Exception) as e:
TestableTest.doClassCleanups()
self.assertEquals(e, 'cleanup1')
def test_with_errors_addCleanUp(self):
ordering = []
class TestableTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
ordering.append('setUpClass')
cls.addClassCleanup(cleanup, ordering)
def setUp(self):
ordering.append('setUp')
self.addCleanup(cleanup, ordering, blowUp=True)
def testNothing(self):
pass
@classmethod
def tearDownClass(cls):
ordering.append('tearDownClass')
result = runTests(TestableTest)
self.assertEqual(result.errors[0][1].splitlines()[-1],
'Exception: CleanUpExc')
self.assertEqual(ordering,
['setUpClass', 'setUp', 'cleanup_exc',
'tearDownClass', 'cleanup_good'])
def test_run_with_errors_addClassCleanUp(self):
ordering = []
class TestableTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
ordering.append('setUpClass')
cls.addClassCleanup(cleanup, ordering, blowUp=True)
def setUp(self):
ordering.append('setUp')
self.addCleanup(cleanup, ordering)
def testNothing(self):
ordering.append('test')
@classmethod
def tearDownClass(cls):
ordering.append('tearDownClass')
result = runTests(TestableTest)
self.assertEqual(result.errors[0][1].splitlines()[-1],
'Exception: CleanUpExc')
self.assertEqual(ordering,
['setUpClass', 'setUp', 'test', 'cleanup_good',
'tearDownClass', 'cleanup_exc'])
def test_with_errors_in_addClassCleanup_and_setUps(self):
ordering = []
class_blow_up = False
method_blow_up = False
class TestableTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
ordering.append('setUpClass')
cls.addClassCleanup(cleanup, ordering, blowUp=True)
if class_blow_up:
raise Exception('ClassExc')
def setUp(self):
ordering.append('setUp')
if method_blow_up:
raise Exception('MethodExc')
def testNothing(self):
ordering.append('test')
@classmethod
def tearDownClass(cls):
ordering.append('tearDownClass')
result = runTests(TestableTest)
self.assertEqual(result.errors[0][1].splitlines()[-1],
'Exception: CleanUpExc')
self.assertEqual(ordering,
['setUpClass', 'setUp', 'test',
'tearDownClass', 'cleanup_exc'])
ordering = []
class_blow_up = True
method_blow_up = False
result = runTests(TestableTest)
self.assertEqual(result.errors[0][1].splitlines()[-1],
'Exception: ClassExc')
self.assertEqual(result.errors[1][1].splitlines()[-1],
'Exception: CleanUpExc')
self.assertEqual(ordering,
['setUpClass', 'cleanup_exc'])
ordering = []
class_blow_up = False
method_blow_up = True
result = runTests(TestableTest)
self.assertEqual(result.errors[0][1].splitlines()[-1],
'Exception: MethodExc')
self.assertEqual(result.errors[1][1].splitlines()[-1],
'Exception: CleanUpExc')
self.assertEqual(ordering,
['setUpClass', 'setUp', 'tearDownClass',
'cleanup_exc'])
class TestModuleCleanUp(unittest.TestCase):
def test_add_and_do_ModuleCleanup(self):
module_cleanups = []
def module_cleanup1(*args, **kwargs):
module_cleanups.append((3, args, kwargs))
def module_cleanup2(*args, **kwargs):
module_cleanups.append((4, args, kwargs))
class Module(object):
unittest.addModuleCleanup(module_cleanup1, 1, 2, 3,
four='hello', five='goodbye')
unittest.addModuleCleanup(module_cleanup2)
self.assertEqual(unittest.case._module_cleanups,
[(module_cleanup1, (1, 2, 3),
dict(four='hello', five='goodbye')),
(module_cleanup2, (), {})])
unittest.case.doModuleCleanups()
self.assertEqual(module_cleanups, [(4, (), {}), (3, (1, 2, 3),
dict(four='hello', five='goodbye'))])
self.assertEqual(unittest.case._module_cleanups, [])
def test_doModuleCleanup_with_errors_in_addModuleCleanup(self):
module_cleanups = []
def module_cleanup_good(*args, **kwargs):
module_cleanups.append((3, args, kwargs))
def module_cleanup_bad(*args, **kwargs):
raise Exception('CleanUpExc')
class Module(object):
unittest.addModuleCleanup(module_cleanup_good, 1, 2, 3,
four='hello', five='goodbye')
unittest.addModuleCleanup(module_cleanup_bad)
self.assertEqual(unittest.case._module_cleanups,
[(module_cleanup_good, (1, 2, 3),
dict(four='hello', five='goodbye')),
(module_cleanup_bad, (), {})])
with self.assertRaises(Exception) as e:
unittest.case.doModuleCleanups()
self.assertEqual(str(e.exception), 'CleanUpExc')
self.assertEqual(unittest.case._module_cleanups, [])
def test_run_module_cleanUp(self):
blowUp = True
ordering = []
class Module(object):
@staticmethod
def setUpModule():
ordering.append('setUpModule')
unittest.addModuleCleanup(cleanup, ordering)
if blowUp:
raise Exception('setUpModule Exc')
@staticmethod
def tearDownModule():
ordering.append('tearDownModule')
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(ordering, ['setUpModule', 'cleanup_good'])
self.assertEqual(result.errors[0][1].splitlines()[-1],
'Exception: setUpModule Exc')
ordering = []
blowUp = False
runTests(TestableTest)
self.assertEqual(ordering,
['setUpModule', 'setUpClass', 'test', 'tearDownClass',
'tearDownModule', 'cleanup_good'])
self.assertEqual(unittest.case._module_cleanups, [])
def test_run_multiple_module_cleanUp(self):
blowUp = True
blowUp2 = False
ordering = []
class Module1(object):
@staticmethod
def setUpModule():
ordering.append('setUpModule')
unittest.addModuleCleanup(cleanup, ordering)
if blowUp:
raise Exception()
@staticmethod
def tearDownModule():
ordering.append('tearDownModule')
class Module2(object):
@staticmethod
def setUpModule():
ordering.append('setUpModule2')
unittest.addModuleCleanup(cleanup, ordering)
if blowUp2:
raise Exception()
@staticmethod
def tearDownModule():
ordering.append('tearDownModule2')
class TestableTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
ordering.append('setUpClass')
def testNothing(self):
ordering.append('test')
@classmethod
def tearDownClass(cls):
ordering.append('tearDownClass')
class TestableTest2(unittest.TestCase):
@classmethod
def setUpClass(cls):
ordering.append('setUpClass2')
def testNothing(self):
ordering.append('test2')
@classmethod
def tearDownClass(cls):
ordering.append('tearDownClass2')
TestableTest.__module__ = 'Module1'
sys.modules['Module1'] = Module1
TestableTest2.__module__ = 'Module2'
sys.modules['Module2'] = Module2
runTests(TestableTest, TestableTest2)
self.assertEqual(ordering, ['setUpModule', 'cleanup_good',
'setUpModule2', 'setUpClass2', 'test2',
'tearDownClass2', 'tearDownModule2',
'cleanup_good'])
ordering = []
blowUp = False
blowUp2 = True
runTests(TestableTest, TestableTest2)
self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test',
'tearDownClass', 'tearDownModule',
'cleanup_good', 'setUpModule2',
'cleanup_good'])
ordering = []
blowUp = False
blowUp2 = False
runTests(TestableTest, TestableTest2)
self.assertEqual(ordering,
['setUpModule', 'setUpClass', 'test', 'tearDownClass',
'tearDownModule', 'cleanup_good', 'setUpModule2',
'setUpClass2', 'test2', 'tearDownClass2',
'tearDownModule2', 'cleanup_good'])
self.assertEqual(unittest.case._module_cleanups, [])
def test_debug_module_executes_cleanUp(self):
ordering = []
class Module(object):
@staticmethod
def setUpModule():
ordering.append('setUpModule')
unittest.addModuleCleanup(cleanup, ordering)
@staticmethod
def tearDownModule():
ordering.append('tearDownModule')
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)
suite.debug()
self.assertEqual(ordering,
['setUpModule', 'setUpClass', 'test', 'tearDownClass',
'tearDownModule', 'cleanup_good'])
self.assertEqual(unittest.case._module_cleanups, [])
def test_with_errors_in_addClassCleanup(self):
ordering = []
class Module(object):
@staticmethod
def setUpModule():
ordering.append('setUpModule')
unittest.addModuleCleanup(cleanup, ordering)
@staticmethod
def tearDownModule():
ordering.append('tearDownModule')
class TestableTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
ordering.append('setUpClass')
cls.addClassCleanup(cleanup, ordering, blowUp=True)
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_exc', 'tearDownModule', 'cleanup_good'])
def test_with_errors_in_addCleanup(self):
ordering = []
class Module(object):
@staticmethod
def setUpModule():
ordering.append('setUpModule')
unittest.addModuleCleanup(cleanup, ordering)
@staticmethod
def tearDownModule():
ordering.append('tearDownModule')
class TestableTest(unittest.TestCase):
def setUp(self):
ordering.append('setUp')
self.addCleanup(cleanup, ordering, blowUp=True)
def testNothing(self):
ordering.append('test')
def tearDown(self):
ordering.append('tearDown')
TestableTest.__module__ = 'Module'
sys.modules['Module'] = Module
result = runTests(TestableTest)
self.assertEqual(result.errors[0][1].splitlines()[-1],
'Exception: CleanUpExc')
self.assertEqual(ordering,
['setUpModule', 'setUp', 'test', 'tearDown',
'cleanup_exc', 'tearDownModule', 'cleanup_good'])
def test_with_errors_in_addModuleCleanup_and_setUps(self):
ordering = []
module_blow_up = False
class_blow_up = False
method_blow_up = False
class Module(object):
@staticmethod
def setUpModule():
ordering.append('setUpModule')
unittest.addModuleCleanup(cleanup, ordering, blowUp=True)
if module_blow_up:
raise Exception('ModuleExc')
@staticmethod
def tearDownModule():
ordering.append('tearDownModule')
class TestableTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
ordering.append('setUpClass')
if class_blow_up:
raise Exception('ClassExc')
def setUp(self):
ordering.append('setUp')
if method_blow_up:
raise Exception('MethodExc')
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', 'setUp', 'test',
'tearDownClass', 'tearDownModule',
'cleanup_exc'])
ordering = []
module_blow_up = True
class_blow_up = False
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(ordering, ['setUpModule', 'cleanup_exc'])
ordering = []
module_blow_up = False
class_blow_up = True
method_blow_up = False
result = runTests(TestableTest)
self.assertEqual(result.errors[0][1].splitlines()[-1],
'Exception: ClassExc')
self.assertEqual(result.errors[1][1].splitlines()[-1],
'Exception: CleanUpExc')
self.assertEqual(ordering, ['setUpModule', 'setUpClass',
'tearDownModule', 'cleanup_exc'])
ordering = []
module_blow_up = False
class_blow_up = False
method_blow_up = True
result = runTests(TestableTest)
self.assertEqual(result.errors[0][1].splitlines()[-1],
'Exception: MethodExc')
self.assertEqual(result.errors[1][1].splitlines()[-1],
'Exception: CleanUpExc')
self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'setUp',
'tearDownClass', 'tearDownModule',
'cleanup_exc'])
def test_module_cleanUp_with_multiple_classes(self):
ordering =[]
def cleanup1():
ordering.append('cleanup1')
def cleanup2():
ordering.append('cleanup2')
def cleanup3():
ordering.append('cleanup3')
class Module(object):
@staticmethod
def setUpModule():
ordering.append('setUpModule')
unittest.addModuleCleanup(cleanup1)
@staticmethod
def tearDownModule():
ordering.append('tearDownModule')
class TestableTest(unittest.TestCase):
def setUp(self):
ordering.append('setUp')
self.addCleanup(cleanup2)
def testNothing(self):
ordering.append('test')
def tearDown(self):
ordering.append('tearDown')
class OtherTestableTest(unittest.TestCase):
def setUp(self):
ordering.append('setUp2')
self.addCleanup(cleanup3)
def testNothing(self):
ordering.append('test2')
def tearDown(self):
ordering.append('tearDown2')
TestableTest.__module__ = 'Module'
OtherTestableTest.__module__ = 'Module'
sys.modules['Module'] = Module
runTests(TestableTest, OtherTestableTest)
self.assertEqual(ordering,
['setUpModule', 'setUp', 'test', 'tearDown',
'cleanup2', 'setUp2', 'test2', 'tearDown2',
'cleanup3', 'tearDownModule', 'cleanup1'])
class Test_TextTestRunner(unittest.TestCase):
"""Tests for TextTestRunner."""