| import io | |
| import os | |
| import sys | |
| import pickle | |
| import subprocess | |
| from test import support | |
| import unittest | |
| from unittest.case import _Outcome | |
| from test.test_unittest.support import ( | |
| BufferedWriter, | |
| LoggingResult, | |
| ResultWithNoStartTestRunStopTestRun, | |
| ) | |
| from test.support.testcase import ExceptionIsLikeMixin | |
| def resultFactory(*_): | |
| return unittest.TestResult() | |
| def getRunner(): | |
| return unittest.TextTestRunner(resultclass=resultFactory, | |
| stream=io.StringIO()) | |
| class CustomError(Exception): | |
| pass | |
| # For test output compat: | |
| CustomErrorRepr = f"{__name__ + '.' if __name__ != '__main__' else ''}CustomError" | |
| 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 CustomError('CleanUpExc') | |
| class TestCM: | |
| def __init__(self, ordering, enter_result=None): | |
| self.ordering = ordering | |
| self.enter_result = enter_result | |
| def __enter__(self): | |
| self.ordering.append('enter') | |
| return self.enter_result | |
| def __exit__(self, *exc_info): | |
| self.ordering.append('exit') | |
| class LacksEnterAndExit: | |
| pass | |
| class LacksEnter: | |
| def __exit__(self, *exc_info): | |
| pass | |
| class LacksExit: | |
| def __enter__(self): | |
| pass | |
| class TestCleanUp(unittest.TestCase): | |
| def testCleanUp(self): | |
| class TestableTest(unittest.TestCase): | |
| def testNothing(self): | |
| pass | |
| test = TestableTest('testNothing') | |
| self.assertEqual(test._cleanups, []) | |
| cleanups = [] | |
| def cleanup1(*args, **kwargs): | |
| cleanups.append((1, args, kwargs)) | |
| def cleanup2(*args, **kwargs): | |
| cleanups.append((2, args, kwargs)) | |
| test.addCleanup(cleanup1, 1, 2, 3, four='hello', five='goodbye') | |
| test.addCleanup(cleanup2) | |
| self.assertEqual(test._cleanups, | |
| [(cleanup1, (1, 2, 3), dict(four='hello', five='goodbye')), | |
| (cleanup2, (), {})]) | |
| self.assertTrue(test.doCleanups()) | |
| self.assertEqual(cleanups, [(2, (), {}), (1, (1, 2, 3), dict(four='hello', five='goodbye'))]) | |
| @support.force_not_colorized | |
| def testCleanUpWithErrors(self): | |
| class TestableTest(unittest.TestCase): | |
| def testNothing(self): | |
| pass | |
| test = TestableTest('testNothing') | |
| result = unittest.TestResult() | |
| outcome = test._outcome = _Outcome(result=result) | |
| CleanUpExc = CustomError('foo') | |
| exc2 = CustomError('bar') | |
| def cleanup1(): | |
| raise CleanUpExc | |
| def cleanup2(): | |
| raise exc2 | |
| test.addCleanup(cleanup1) | |
| test.addCleanup(cleanup2) | |
| self.assertFalse(test.doCleanups()) | |
| self.assertFalse(outcome.success) | |
| (_, msg2), (_, msg1) = result.errors | |
| self.assertIn('in cleanup1', msg1) | |
| self.assertIn('raise CleanUpExc', msg1) | |
| self.assertIn(f'{CustomErrorRepr}: foo', msg1) | |
| self.assertIn('in cleanup2', msg2) | |
| self.assertIn('raise exc2', msg2) | |
| self.assertIn(f'{CustomErrorRepr}: bar', msg2) | |
| def testCleanupInRun(self): | |
| blowUp = False | |
| ordering = [] | |
| class TestableTest(unittest.TestCase): | |
| def setUp(self): | |
| ordering.append('setUp') | |
| test.addCleanup(cleanup2) | |
| if blowUp: | |
| raise CustomError('foo') | |
| def testNothing(self): | |
| ordering.append('test') | |
| test.addCleanup(cleanup3) | |
| def tearDown(self): | |
| ordering.append('tearDown') | |
| test = TestableTest('testNothing') | |
| def cleanup1(): | |
| ordering.append('cleanup1') | |
| def cleanup2(): | |
| ordering.append('cleanup2') | |
| def cleanup3(): | |
| ordering.append('cleanup3') | |
| test.addCleanup(cleanup1) | |
| def success(some_test): | |
| self.assertEqual(some_test, test) | |
| ordering.append('success') | |
| result = unittest.TestResult() | |
| result.addSuccess = success | |
| test.run(result) | |
| self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup3', | |
| 'cleanup2', 'cleanup1', 'success']) | |
| blowUp = True | |
| ordering = [] | |
| test = TestableTest('testNothing') | |
| test.addCleanup(cleanup1) | |
| test.run(result) | |
| self.assertEqual(ordering, ['setUp', 'cleanup2', 'cleanup1']) | |
| def testTestCaseDebugExecutesCleanups(self): | |
| ordering = [] | |
| class TestableTest(unittest.TestCase): | |
| def setUp(self): | |
| ordering.append('setUp') | |
| self.addCleanup(cleanup1) | |
| def testNothing(self): | |
| ordering.append('test') | |
| self.addCleanup(cleanup3) | |
| def tearDown(self): | |
| ordering.append('tearDown') | |
| test.addCleanup(cleanup4) | |
| test = TestableTest('testNothing') | |
| def cleanup1(): | |
| ordering.append('cleanup1') | |
| test.addCleanup(cleanup2) | |
| def cleanup2(): | |
| ordering.append('cleanup2') | |
| def cleanup3(): | |
| ordering.append('cleanup3') | |
| def cleanup4(): | |
| ordering.append('cleanup4') | |
| test.debug() | |
| self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup4', | |
| 'cleanup3', 'cleanup1', 'cleanup2']) | |
| def test_enterContext(self): | |
| class TestableTest(unittest.TestCase): | |
| def testNothing(self): | |
| pass | |
| test = TestableTest('testNothing') | |
| cleanups = [] | |
| test.addCleanup(cleanups.append, 'cleanup1') | |
| cm = TestCM(cleanups, 42) | |
| self.assertEqual(test.enterContext(cm), 42) | |
| test.addCleanup(cleanups.append, 'cleanup2') | |
| self.assertTrue(test.doCleanups()) | |
| self.assertEqual(cleanups, ['enter', 'cleanup2', 'exit', 'cleanup1']) | |
| def test_enterContext_arg_errors(self): | |
| class TestableTest(unittest.TestCase): | |
| def testNothing(self): | |
| pass | |
| test = TestableTest('testNothing') | |
| with self.assertRaisesRegex(TypeError, 'the context manager'): | |
| test.enterContext(LacksEnterAndExit()) | |
| with self.assertRaisesRegex(TypeError, 'the context manager'): | |
| test.enterContext(LacksEnter()) | |
| with self.assertRaisesRegex(TypeError, 'the context manager'): | |
| test.enterContext(LacksExit()) | |
| self.assertEqual(test._cleanups, []) | |
| @support.force_not_colorized_test_class | |
| 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 CustomError() | |
| 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_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 CustomError() | |
| 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 | |
| def tearDownClass(cls): | |
| ordering.append('tearDownClass') | |
| suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) | |
| suite.debug() | |
| self.assertEqual(ordering, | |
| ['setUpClass', 'test', 'tearDownClass', 'cleanup_good']) | |
| ordering = [] | |
| blowUp = True | |
| suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) | |
| with self.assertRaises(CustomError) 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): | |
| ordering.append('tearDownClass') | |
| raise CustomError('TearDownClassExc') | |
| suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) | |
| with self.assertRaises(CustomError) as cm: | |
| suite.debug() | |
| self.assertEqual(str(cm.exception), 'TearDownClassExc') | |
| self.assertEqual(ordering, ['setUpClass', 'test', 'tearDownClass']) | |
| self.assertTrue(TestableTest._class_cleanups) | |
| TestableTest._class_cleanups.clear() | |
| ordering = [] | |
| blowUp = True | |
| suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) | |
| with self.assertRaises(CustomError) as cm: | |
| suite.debug() | |
| self.assertEqual(str(cm.exception), 'TearDownClassExc') | |
| self.assertEqual(ordering, ['setUpClass', 'test', 'tearDownClass']) | |
| self.assertTrue(TestableTest._class_cleanups) | |
| TestableTest._class_cleanups.clear() | |
| def test_doClassCleanups_with_errors_addClassCleanUp(self): | |
| class TestableTest(unittest.TestCase): | |
| def testNothing(self): | |
| pass | |
| def cleanup1(): | |
| raise CustomError('cleanup1') | |
| def cleanup2(): | |
| raise CustomError('cleanup2') | |
| TestableTest.addClassCleanup(cleanup1) | |
| TestableTest.addClassCleanup(cleanup2) | |
| TestableTest.doClassCleanups() | |
| self.assertEqual(len(TestableTest.tearDown_exceptions), 2) | |
| e1, e2 = TestableTest.tearDown_exceptions | |
| self.assertIsInstance(e1[1], CustomError) | |
| self.assertEqual(str(e1[1]), 'cleanup2') | |
| self.assertIsInstance(e2[1], CustomError) | |
| self.assertEqual(str(e2[1]), '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], | |
| f'{CustomErrorRepr}: 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], | |
| f'{CustomErrorRepr}: 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 CustomError('ClassExc') | |
| def setUp(self): | |
| ordering.append('setUp') | |
| if method_blow_up: | |
| raise CustomError('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], | |
| f'{CustomErrorRepr}: 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], | |
| f'{CustomErrorRepr}: ClassExc') | |
| self.assertEqual(result.errors[1][1].splitlines()[-1], | |
| f'{CustomErrorRepr}: 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], | |
| f'{CustomErrorRepr}: MethodExc') | |
| self.assertEqual(result.errors[1][1].splitlines()[-1], | |
| f'{CustomErrorRepr}: CleanUpExc') | |
| self.assertEqual(ordering, | |
| ['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 CustomError('TearDownExc') | |
| result = runTests(TestableTest) | |
| self.assertEqual(result.errors[0][1].splitlines()[-1], | |
| f'{CustomErrorRepr}: TearDownExc') | |
| self.assertEqual(ordering, | |
| ['setUpClass', 'test', 'tearDownClass', 'cleanup_good']) | |
| def test_enterClassContext(self): | |
| class TestableTest(unittest.TestCase): | |
| def testNothing(self): | |
| pass | |
| cleanups = [] | |
| TestableTest.addClassCleanup(cleanups.append, 'cleanup1') | |
| cm = TestCM(cleanups, 42) | |
| self.assertEqual(TestableTest.enterClassContext(cm), 42) | |
| TestableTest.addClassCleanup(cleanups.append, 'cleanup2') | |
| TestableTest.doClassCleanups() | |
| self.assertEqual(cleanups, ['enter', 'cleanup2', 'exit', 'cleanup1']) | |
| def test_enterClassContext_arg_errors(self): | |
| class TestableTest(unittest.TestCase): | |
| def testNothing(self): | |
| pass | |
| with self.assertRaisesRegex(TypeError, 'the context manager'): | |
| TestableTest.enterClassContext(LacksEnterAndExit()) | |
| with self.assertRaisesRegex(TypeError, 'the context manager'): | |
| TestableTest.enterClassContext(LacksEnter()) | |
| with self.assertRaisesRegex(TypeError, 'the context manager'): | |
| TestableTest.enterClassContext(LacksExit()) | |
| self.assertEqual(TestableTest._class_cleanups, []) | |
| def test_run_nested_test(self): | |
| ordering = [] | |
| class InnerTest(unittest.TestCase): | |
| @classmethod | |
| def setUpClass(cls): | |
| ordering.append('inner setup') | |
| cls.addClassCleanup(ordering.append, 'inner cleanup') | |
| def test(self): | |
| ordering.append('inner test') | |
| class OuterTest(unittest.TestCase): | |
| @classmethod | |
| def setUpClass(cls): | |
| ordering.append('outer setup') | |
| cls.addClassCleanup(ordering.append, 'outer cleanup') | |
| def test(self): | |
| ordering.append('start outer test') | |
| runTests(InnerTest) | |
| ordering.append('end outer test') | |
| runTests(OuterTest) | |
| self.assertEqual(ordering, [ | |
| 'outer setup', 'start outer test', | |
| 'inner setup', 'inner test', 'inner cleanup', | |
| 'end outer test', 'outer cleanup']) | |
| def test_run_empty_suite_error_message(self): | |
| class EmptyTest(unittest.TestCase): | |
| pass | |
| suite = unittest.defaultTestLoader.loadTestsFromTestCase(EmptyTest) | |
| runner = getRunner() | |
| runner.run(suite) | |
| self.assertIn("\nNO TESTS RAN\n", runner.stream.getvalue()) | |
| @support.force_not_colorized_test_class | |
| class TestModuleCleanUp(ExceptionIsLikeMixin, 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 CustomError('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.assertExceptionIsLike(e.exception, | |
| ExceptionGroup('module cleanup failed', | |
| [CustomError('CleanUpExc')])) | |
| self.assertEqual(unittest.case._module_cleanups, []) | |
| def test_doModuleCleanup_with_multiple_errors_in_addModuleCleanup(self): | |
| def module_cleanup_bad1(): | |
| raise TypeError('CleanUpExc1') | |
| def module_cleanup_bad2(): | |
| raise ValueError('CleanUpExc2') | |
| class Module: | |
| unittest.addModuleCleanup(module_cleanup_bad1) | |
| unittest.addModuleCleanup(module_cleanup_bad2) | |
| with self.assertRaises(ExceptionGroup) as e: | |
| unittest.case.doModuleCleanups() | |
| self.assertExceptionIsLike(e.exception, | |
| ExceptionGroup('module cleanup failed', [ | |
| ValueError('CleanUpExc2'), | |
| TypeError('CleanUpExc1'), | |
| ])) | |
| def test_doModuleCleanup_with_exception_group_in_addModuleCleanup(self): | |
| def module_cleanup_bad(): | |
| raise ExceptionGroup('CleanUpExc', [ | |
| ValueError('CleanUpExc2'), | |
| TypeError('CleanUpExc1'), | |
| ]) | |
| class Module: | |
| unittest.addModuleCleanup(module_cleanup_bad) | |
| with self.assertRaises(ExceptionGroup) as e: | |
| unittest.case.doModuleCleanups() | |
| self.assertExceptionIsLike(e.exception, | |
| ExceptionGroup('module cleanup failed', [ | |
| ExceptionGroup('CleanUpExc', [ | |
| ValueError('CleanUpExc2'), | |
| TypeError('CleanUpExc1'), | |
| ]), | |
| ])) | |
| def test_addModuleCleanup_arg_errors(self): | |
| cleanups = [] | |
| def cleanup(*args, **kwargs): | |
| cleanups.append((args, kwargs)) | |
| class Module(object): | |
| unittest.addModuleCleanup(cleanup, 1, 2, function='hello') | |
| with self.assertRaises(TypeError): | |
| unittest.addModuleCleanup(function=cleanup, arg='hello') | |
| with self.assertRaises(TypeError): | |
| unittest.addModuleCleanup() | |
| unittest.case.doModuleCleanups() | |
| self.assertEqual(cleanups, | |
| [((1, 2), {'function': 'hello'})]) | |
| 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 CustomError('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], | |
| f'{CustomErrorRepr}: 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 CustomError() | |
| @staticmethod | |
| def tearDownModule(): | |
| ordering.append('tearDownModule') | |
| class Module2(object): | |
| @staticmethod | |
| def setUpModule(): | |
| ordering.append('setUpModule2') | |
| unittest.addModuleCleanup(cleanup, ordering) | |
| if blowUp2: | |
| raise CustomError() | |
| @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_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(): | |
| ordering.append('tearDownModule') | |
| raise CustomError('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], | |
| f'{CustomErrorRepr}: CleanUpExc') | |
| self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', | |
| 'tearDownClass', 'tearDownModule', | |
| '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') | |
| 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, []) | |
| ordering = [] | |
| blowUp = True | |
| suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) | |
| with self.assertRaises(Exception) as cm: | |
| suite.debug() | |
| self.assertExceptionIsLike(cm.exception, | |
| ExceptionGroup('module cleanup failed', | |
| [CustomError('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(): | |
| ordering.append('tearDownModule') | |
| raise CustomError('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(CustomError) as cm: | |
| suite.debug() | |
| self.assertEqual(str(cm.exception), 'TearDownModuleExc') | |
| self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', | |
| 'tearDownClass', 'tearDownModule']) | |
| self.assertTrue(unittest.case._module_cleanups) | |
| unittest.case._module_cleanups.clear() | |
| ordering = [] | |
| blowUp = True | |
| suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) | |
| with self.assertRaises(CustomError) as cm: | |
| suite.debug() | |
| self.assertEqual(str(cm.exception), 'TearDownModuleExc') | |
| self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', | |
| 'tearDownClass', 'tearDownModule']) | |
| self.assertTrue(unittest.case._module_cleanups) | |
| unittest.case._module_cleanups.clear() | |
| def test_addClassCleanup_arg_errors(self): | |
| cleanups = [] | |
| def cleanup(*args, **kwargs): | |
| cleanups.append((args, kwargs)) | |
| class TestableTest(unittest.TestCase): | |
| @classmethod | |
| def setUpClass(cls): | |
| cls.addClassCleanup(cleanup, 1, 2, function=3, cls=4) | |
| with self.assertRaises(TypeError): | |
| cls.addClassCleanup(function=cleanup, arg='hello') | |
| def testNothing(self): | |
| pass | |
| with self.assertRaises(TypeError): | |
| TestableTest.addClassCleanup() | |
| with self.assertRaises(TypeError): | |
| unittest.TestCase.addCleanup(cls=TestableTest(), function=cleanup) | |
| runTests(TestableTest) | |
| self.assertEqual(cleanups, | |
| [((1, 2), {'function': 3, 'cls': 4})]) | |
| def test_addCleanup_arg_errors(self): | |
| cleanups = [] | |
| def cleanup(*args, **kwargs): | |
| cleanups.append((args, kwargs)) | |
| class TestableTest(unittest.TestCase): | |
| def setUp(self2): | |
| self2.addCleanup(cleanup, 1, 2, function=3, self=4) | |
| with self.assertRaises(TypeError): | |
| self2.addCleanup(function=cleanup, arg='hello') | |
| def testNothing(self): | |
| pass | |
| with self.assertRaises(TypeError): | |
| TestableTest().addCleanup() | |
| with self.assertRaises(TypeError): | |
| unittest.TestCase.addCleanup(self=TestableTest(), function=cleanup) | |
| runTests(TestableTest) | |
| self.assertEqual(cleanups, | |
| [((1, 2), {'function': 3, 'self': 4})]) | |
| 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], | |
| f'{CustomErrorRepr}: 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], | |
| f'{CustomErrorRepr}: 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 CustomError('ModuleExc') | |
| @staticmethod | |
| def tearDownModule(): | |
| ordering.append('tearDownModule') | |
| class TestableTest(unittest.TestCase): | |
| @classmethod | |
| def setUpClass(cls): | |
| ordering.append('setUpClass') | |
| if class_blow_up: | |
| raise CustomError('ClassExc') | |
| def setUp(self): | |
| ordering.append('setUp') | |
| if method_blow_up: | |
| raise CustomError('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], | |
| f'{CustomErrorRepr}: 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], | |
| f'{CustomErrorRepr}: ModuleExc') | |
| self.assertEqual(result.errors[1][1].splitlines()[-1], | |
| f'{CustomErrorRepr}: CleanUpExc') | |
| 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], | |
| f'{CustomErrorRepr}: ClassExc') | |
| self.assertEqual(result.errors[1][1].splitlines()[-1], | |
| f'{CustomErrorRepr}: 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], | |
| f'{CustomErrorRepr}: MethodExc') | |
| self.assertEqual(result.errors[1][1].splitlines()[-1], | |
| f'{CustomErrorRepr}: 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']) | |
| def test_enterModuleContext(self): | |
| cleanups = [] | |
| unittest.addModuleCleanup(cleanups.append, 'cleanup1') | |
| cm = TestCM(cleanups, 42) | |
| self.assertEqual(unittest.enterModuleContext(cm), 42) | |
| unittest.addModuleCleanup(cleanups.append, 'cleanup2') | |
| unittest.case.doModuleCleanups() | |
| self.assertEqual(cleanups, ['enter', 'cleanup2', 'exit', 'cleanup1']) | |
| def test_enterModuleContext_arg_errors(self): | |
| class TestableTest(unittest.TestCase): | |
| def testNothing(self): | |
| pass | |
| with self.assertRaisesRegex(TypeError, 'the context manager'): | |
| unittest.enterModuleContext(LacksEnterAndExit()) | |
| with self.assertRaisesRegex(TypeError, 'the context manager'): | |
| unittest.enterModuleContext(LacksEnter()) | |
| with self.assertRaisesRegex(TypeError, 'the context manager'): | |
| unittest.enterModuleContext(LacksExit()) | |
| self.assertEqual(unittest.case._module_cleanups, []) | |
| class Test_TextTestRunner(unittest.TestCase): | |
| """Tests for TextTestRunner.""" | |
| def setUp(self): | |
| # clean the environment from pre-existing PYTHONWARNINGS to make | |
| # test_warnings results consistent | |
| self.pythonwarnings = os.environ.get('PYTHONWARNINGS') | |
| if self.pythonwarnings: | |
| del os.environ['PYTHONWARNINGS'] | |
| def tearDown(self): | |
| # bring back pre-existing PYTHONWARNINGS if present | |
| if self.pythonwarnings: | |
| os.environ['PYTHONWARNINGS'] = self.pythonwarnings | |
| def test_init(self): | |
| runner = unittest.TextTestRunner() | |
| self.assertFalse(runner.failfast) | |
| self.assertFalse(runner.buffer) | |
| self.assertEqual(runner.verbosity, 1) | |
| self.assertEqual(runner.warnings, None) | |
| self.assertTrue(runner.descriptions) | |
| self.assertEqual(runner.resultclass, unittest.TextTestResult) | |
| self.assertFalse(runner.tb_locals) | |
| self.assertIsNone(runner.durations) | |
| def test_multiple_inheritance(self): | |
| class AResult(unittest.TestResult): | |
| def __init__(self, stream, descriptions, verbosity): | |
| super(AResult, self).__init__(stream, descriptions, verbosity) | |
| class ATextResult(unittest.TextTestResult, AResult): | |
| pass | |
| # This used to raise an exception due to TextTestResult not passing | |
| # on arguments in its __init__ super call | |
| ATextResult(None, None, 1) | |
| def testBufferAndFailfast(self): | |
| class Test(unittest.TestCase): | |
| def testFoo(self): | |
| pass | |
| result = unittest.TestResult() | |
| runner = unittest.TextTestRunner(stream=io.StringIO(), failfast=True, | |
| buffer=True) | |
| # Use our result object | |
| runner._makeResult = lambda: result | |
| runner.run(Test('testFoo')) | |
| self.assertTrue(result.failfast) | |
| self.assertTrue(result.buffer) | |
| def test_locals(self): | |
| runner = unittest.TextTestRunner(stream=io.StringIO(), tb_locals=True) | |
| result = runner.run(unittest.TestSuite()) | |
| self.assertEqual(True, result.tb_locals) | |
| def testRunnerRegistersResult(self): | |
| class Test(unittest.TestCase): | |
| def testFoo(self): | |
| pass | |
| originalRegisterResult = unittest.runner.registerResult | |
| def cleanup(): | |
| unittest.runner.registerResult = originalRegisterResult | |
| self.addCleanup(cleanup) | |
| result = unittest.TestResult() | |
| runner = unittest.TextTestRunner(stream=io.StringIO()) | |
| # Use our result object | |
| runner._makeResult = lambda: result | |
| self.wasRegistered = 0 | |
| def fakeRegisterResult(thisResult): | |
| self.wasRegistered += 1 | |
| self.assertEqual(thisResult, result) | |
| unittest.runner.registerResult = fakeRegisterResult | |
| runner.run(unittest.TestSuite()) | |
| self.assertEqual(self.wasRegistered, 1) | |
| def test_works_with_result_without_startTestRun_stopTestRun(self): | |
| class OldTextResult(ResultWithNoStartTestRunStopTestRun): | |
| separator2 = '' | |
| def printErrors(self): | |
| pass | |
| class Runner(unittest.TextTestRunner): | |
| def __init__(self): | |
| super(Runner, self).__init__(io.StringIO()) | |
| def _makeResult(self): | |
| return OldTextResult() | |
| runner = Runner() | |
| runner.run(unittest.TestSuite()) | |
| def test_startTestRun_stopTestRun_called(self): | |
| class LoggingTextResult(LoggingResult): | |
| separator2 = '' | |
| def printErrors(self): | |
| pass | |
| class LoggingRunner(unittest.TextTestRunner): | |
| def __init__(self, events): | |
| super(LoggingRunner, self).__init__(io.StringIO()) | |
| self._events = events | |
| def _makeResult(self): | |
| return LoggingTextResult(self._events) | |
| events = [] | |
| runner = LoggingRunner(events) | |
| runner.run(unittest.TestSuite()) | |
| expected = ['startTestRun', 'stopTestRun'] | |
| self.assertEqual(events, expected) | |
| def test_pickle_unpickle(self): | |
| # Issue #7197: a TextTestRunner should be (un)pickleable. This is | |
| # required by test_multiprocessing under Windows (in verbose mode). | |
| stream = io.StringIO("foo") | |
| runner = unittest.TextTestRunner(stream) | |
| for protocol in range(2, pickle.HIGHEST_PROTOCOL + 1): | |
| s = pickle.dumps(runner, protocol) | |
| obj = pickle.loads(s) | |
| # StringIO objects never compare equal, a cheap test instead. | |
| self.assertEqual(obj.stream.getvalue(), stream.getvalue()) | |
| def test_resultclass(self): | |
| def MockResultClass(*args): | |
| return args | |
| STREAM = object() | |
| DESCRIPTIONS = object() | |
| VERBOSITY = object() | |
| runner = unittest.TextTestRunner(STREAM, DESCRIPTIONS, VERBOSITY, | |
| resultclass=MockResultClass) | |
| self.assertEqual(runner.resultclass, MockResultClass) | |
| expectedresult = (runner.stream, DESCRIPTIONS, VERBOSITY) | |
| self.assertEqual(runner._makeResult(), expectedresult) | |
| def test_verbosity_set_on_result(self): | |
| class Suite: | |
| def __call__(self, result): | |
| pass | |
| for verbosity in range(4): | |
| with self.subTest(verbosity=verbosity): | |
| runner = unittest.TextTestRunner(io.StringIO(), | |
| verbosity=verbosity) | |
| result = runner.run(Suite()) | |
| self.assertEqual(result.verbosity, verbosity) | |
| def test_verbosity_set_on_filtering_result(self): | |
| # A result class is free to filter the verbosity which its | |
| # constructor gets, as test.libregrtest does. | |
| class FilteringResult(unittest.TextTestResult): | |
| def __init__(self, stream, descriptions, verbosity): | |
| super().__init__(stream, descriptions, | |
| 2 if verbosity else 0) | |
| class Suite: | |
| def __call__(self, result): | |
| pass | |
| runner = unittest.TextTestRunner(io.StringIO(), verbosity=3, | |
| resultclass=FilteringResult) | |
| result = runner.run(Suite()) | |
| self.assertEqual(result.verbosity, 3) | |
| @support.force_not_colorized | |
| @support.requires_subprocess() | |
| def test_warnings(self): | |
| """ | |
| Check that warnings argument of TextTestRunner correctly affects the | |
| behavior of the warnings. | |
| """ | |
| # see #10535 and the _test_warnings file for more information | |
| def get_parse_out_err(p): | |
| return [b.splitlines() for b in p.communicate()] | |
| opts = dict(stdout=subprocess.PIPE, stderr=subprocess.PIPE, | |
| cwd=os.path.dirname(__file__)) | |
| # no args -> all the warnings are printed, unittest warnings only once | |
| p = subprocess.Popen([sys.executable, '-E', '_test_warnings.py'], **opts) | |
| with p: | |
| out, err = get_parse_out_err(p) | |
| self.assertIn(b'OK', err) | |
| # check that the total number of warnings in the output is correct | |
| self.assertEqual(len(out), 10) | |
| # check that the numbers of the different kind of warnings is correct | |
| for msg in [b'dw', b'iw', b'uw']: | |
| self.assertEqual(out.count(msg), 3) | |
| for msg in [b'rw']: | |
| self.assertEqual(out.count(msg), 1) | |
| args_list = ( | |
| # passing 'ignore' as warnings arg -> no warnings | |
| [sys.executable, '_test_warnings.py', 'ignore'], | |
| # -W doesn't affect the result if the arg is passed | |
| [sys.executable, '-Wa', '_test_warnings.py', 'ignore'], | |
| # -W affects the result if the arg is not passed | |
| [sys.executable, '-Wi', '_test_warnings.py'] | |
| ) | |
| # in all these cases no warnings are printed | |
| for args in args_list: | |
| p = subprocess.Popen(args, **opts) | |
| with p: | |
| out, err = get_parse_out_err(p) | |
| self.assertIn(b'OK', err) | |
| self.assertEqual(len(out), 0) | |
| # passing 'always' as warnings arg -> all the warnings printed, | |
| # unittest warnings only once | |
| p = subprocess.Popen([sys.executable, '_test_warnings.py', 'always'], | |
| **opts) | |
| with p: | |
| out, err = get_parse_out_err(p) | |
| self.assertIn(b'OK', err) | |
| self.assertEqual(len(out), 12) | |
| for msg in [b'dw', b'iw', b'uw', b'rw']: | |
| self.assertEqual(out.count(msg), 3) | |
| def testStdErrLookedUpAtInstantiationTime(self): | |
| # see issue 10786 | |
| old_stderr = sys.stderr | |
| f = io.StringIO() | |
| sys.stderr = f | |
| try: | |
| runner = unittest.TextTestRunner() | |
| self.assertTrue(runner.stream.stream is f) | |
| finally: | |
| sys.stderr = old_stderr | |
| def testSpecifiedStreamUsed(self): | |
| # see issue 10786 | |
| f = io.StringIO() | |
| runner = unittest.TextTestRunner(f) | |
| self.assertTrue(runner.stream.stream is f) | |
| def test_durations(self): | |
| def run(test, *, expect_durations=True): | |
| stream = BufferedWriter() | |
| runner = unittest.TextTestRunner(stream=stream, durations=5, verbosity=2) | |
| result = runner.run(test) | |
| self.assertEqual(result.durations, 5) | |
| stream.flush() | |
| text = stream.getvalue() | |
| regex = r"\n\d+.\d\d\ds" | |
| if expect_durations: | |
| self.assertEqual(len(result.collectedDurations), 1) | |
| self.assertIn('Slowest test durations', text) | |
| self.assertRegex(text, regex) | |
| else: | |
| self.assertEqual(len(result.collectedDurations), 0) | |
| self.assertNotIn('Slowest test durations', text) | |
| self.assertNotRegex(text, regex) | |
| # success | |
| class Foo(unittest.TestCase): | |
| def test_1(self): | |
| pass | |
| run(Foo('test_1'), expect_durations=True) | |
| # failure | |
| class Foo(unittest.TestCase): | |
| def test_1(self): | |
| self.assertEqual(0, 1) | |
| run(Foo('test_1'), expect_durations=True) | |
| # error | |
| class Foo(unittest.TestCase): | |
| def test_1(self): | |
| 1 / 0 | |
| run(Foo('test_1'), expect_durations=True) | |
| # error in setUp and tearDown | |
| class Foo(unittest.TestCase): | |
| def setUp(self): | |
| 1 / 0 | |
| tearDown = setUp | |
| def test_1(self): | |
| pass | |
| run(Foo('test_1'), expect_durations=True) | |
| # skip (expect no durations) | |
| class Foo(unittest.TestCase): | |
| @unittest.skip("reason") | |
| def test_1(self): | |
| pass | |
| run(Foo('test_1'), expect_durations=False) | |
| if __name__ == "__main__": | |
| unittest.main() |