1import io 2import os 3import sys 4import pickle 5import subprocess 6from test import support 7 8import unittest 9from unittest.case import _Outcome 10 11from unittest.test.support import (LoggingResult, 12 ResultWithNoStartTestRunStopTestRun) 13 14 15def resultFactory(*_): 16 return unittest.TestResult() 17 18 19def getRunner(): 20 return unittest.TextTestRunner(resultclass=resultFactory, 21 stream=io.StringIO()) 22 23 24def runTests(*cases): 25 suite = unittest.TestSuite() 26 for case in cases: 27 tests = unittest.defaultTestLoader.loadTestsFromTestCase(case) 28 suite.addTests(tests) 29 30 runner = getRunner() 31 32 # creating a nested suite exposes some potential bugs 33 realSuite = unittest.TestSuite() 34 realSuite.addTest(suite) 35 # adding empty suites to the end exposes potential bugs 36 suite.addTest(unittest.TestSuite()) 37 realSuite.addTest(unittest.TestSuite()) 38 return runner.run(realSuite) 39 40 41def cleanup(ordering, blowUp=False): 42 if not blowUp: 43 ordering.append('cleanup_good') 44 else: 45 ordering.append('cleanup_exc') 46 raise Exception('CleanUpExc') 47 48 49class TestCM: 50 def __init__(self, ordering, enter_result=None): 51 self.ordering = ordering 52 self.enter_result = enter_result 53 54 def __enter__(self): 55 self.ordering.append('enter') 56 return self.enter_result 57 58 def __exit__(self, *exc_info): 59 self.ordering.append('exit') 60 61 62class LacksEnterAndExit: 63 pass 64class LacksEnter: 65 def __exit__(self, *exc_info): 66 pass 67class LacksExit: 68 def __enter__(self): 69 pass 70 71 72class TestCleanUp(unittest.TestCase): 73 def testCleanUp(self): 74 class TestableTest(unittest.TestCase): 75 def testNothing(self): 76 pass 77 78 test = TestableTest('testNothing') 79 self.assertEqual(test._cleanups, []) 80 81 cleanups = [] 82 83 def cleanup1(*args, **kwargs): 84 cleanups.append((1, args, kwargs)) 85 86 def cleanup2(*args, **kwargs): 87 cleanups.append((2, args, kwargs)) 88 89 test.addCleanup(cleanup1, 1, 2, 3, four='hello', five='goodbye') 90 test.addCleanup(cleanup2) 91 92 self.assertEqual(test._cleanups, 93 [(cleanup1, (1, 2, 3), dict(four='hello', five='goodbye')), 94 (cleanup2, (), {})]) 95 96 self.assertTrue(test.doCleanups()) 97 self.assertEqual(cleanups, [(2, (), {}), (1, (1, 2, 3), dict(four='hello', five='goodbye'))]) 98 99 def testCleanUpWithErrors(self): 100 class TestableTest(unittest.TestCase): 101 def testNothing(self): 102 pass 103 104 test = TestableTest('testNothing') 105 result = unittest.TestResult() 106 outcome = test._outcome = _Outcome(result=result) 107 108 CleanUpExc = Exception('foo') 109 exc2 = Exception('bar') 110 def cleanup1(): 111 raise CleanUpExc 112 113 def cleanup2(): 114 raise exc2 115 116 test.addCleanup(cleanup1) 117 test.addCleanup(cleanup2) 118 119 self.assertFalse(test.doCleanups()) 120 self.assertFalse(outcome.success) 121 122 (_, msg2), (_, msg1) = result.errors 123 self.assertIn('in cleanup1', msg1) 124 self.assertIn('raise CleanUpExc', msg1) 125 self.assertIn('Exception: foo', msg1) 126 self.assertIn('in cleanup2', msg2) 127 self.assertIn('raise exc2', msg2) 128 self.assertIn('Exception: bar', msg2) 129 130 def testCleanupInRun(self): 131 blowUp = False 132 ordering = [] 133 134 class TestableTest(unittest.TestCase): 135 def setUp(self): 136 ordering.append('setUp') 137 test.addCleanup(cleanup2) 138 if blowUp: 139 raise Exception('foo') 140 141 def testNothing(self): 142 ordering.append('test') 143 test.addCleanup(cleanup3) 144 145 def tearDown(self): 146 ordering.append('tearDown') 147 148 test = TestableTest('testNothing') 149 150 def cleanup1(): 151 ordering.append('cleanup1') 152 def cleanup2(): 153 ordering.append('cleanup2') 154 def cleanup3(): 155 ordering.append('cleanup3') 156 test.addCleanup(cleanup1) 157 158 def success(some_test): 159 self.assertEqual(some_test, test) 160 ordering.append('success') 161 162 result = unittest.TestResult() 163 result.addSuccess = success 164 165 test.run(result) 166 self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup3', 167 'cleanup2', 'cleanup1', 'success']) 168 169 blowUp = True 170 ordering = [] 171 test = TestableTest('testNothing') 172 test.addCleanup(cleanup1) 173 test.run(result) 174 self.assertEqual(ordering, ['setUp', 'cleanup2', 'cleanup1']) 175 176 def testTestCaseDebugExecutesCleanups(self): 177 ordering = [] 178 179 class TestableTest(unittest.TestCase): 180 def setUp(self): 181 ordering.append('setUp') 182 self.addCleanup(cleanup1) 183 184 def testNothing(self): 185 ordering.append('test') 186 self.addCleanup(cleanup3) 187 188 def tearDown(self): 189 ordering.append('tearDown') 190 test.addCleanup(cleanup4) 191 192 test = TestableTest('testNothing') 193 194 def cleanup1(): 195 ordering.append('cleanup1') 196 test.addCleanup(cleanup2) 197 def cleanup2(): 198 ordering.append('cleanup2') 199 def cleanup3(): 200 ordering.append('cleanup3') 201 def cleanup4(): 202 ordering.append('cleanup4') 203 204 test.debug() 205 self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup4', 206 'cleanup3', 'cleanup1', 'cleanup2']) 207 208 209 def test_enterContext(self): 210 class TestableTest(unittest.TestCase): 211 def testNothing(self): 212 pass 213 214 test = TestableTest('testNothing') 215 cleanups = [] 216 217 test.addCleanup(cleanups.append, 'cleanup1') 218 cm = TestCM(cleanups, 42) 219 self.assertEqual(test.enterContext(cm), 42) 220 test.addCleanup(cleanups.append, 'cleanup2') 221 222 self.assertTrue(test.doCleanups()) 223 self.assertEqual(cleanups, ['enter', 'cleanup2', 'exit', 'cleanup1']) 224 225 def test_enterContext_arg_errors(self): 226 class TestableTest(unittest.TestCase): 227 def testNothing(self): 228 pass 229 230 test = TestableTest('testNothing') 231 232 with self.assertRaisesRegex(TypeError, 'the context manager'): 233 test.enterContext(LacksEnterAndExit()) 234 with self.assertRaisesRegex(TypeError, 'the context manager'): 235 test.enterContext(LacksEnter()) 236 with self.assertRaisesRegex(TypeError, 'the context manager'): 237 test.enterContext(LacksExit()) 238 239 self.assertEqual(test._cleanups, []) 240 241 242class TestClassCleanup(unittest.TestCase): 243 def test_addClassCleanUp(self): 244 class TestableTest(unittest.TestCase): 245 def testNothing(self): 246 pass 247 test = TestableTest('testNothing') 248 self.assertEqual(test._class_cleanups, []) 249 class_cleanups = [] 250 251 def class_cleanup1(*args, **kwargs): 252 class_cleanups.append((3, args, kwargs)) 253 254 def class_cleanup2(*args, **kwargs): 255 class_cleanups.append((4, args, kwargs)) 256 257 TestableTest.addClassCleanup(class_cleanup1, 1, 2, 3, 258 four='hello', five='goodbye') 259 TestableTest.addClassCleanup(class_cleanup2) 260 261 self.assertEqual(test._class_cleanups, 262 [(class_cleanup1, (1, 2, 3), 263 dict(four='hello', five='goodbye')), 264 (class_cleanup2, (), {})]) 265 266 TestableTest.doClassCleanups() 267 self.assertEqual(class_cleanups, [(4, (), {}), (3, (1, 2, 3), 268 dict(four='hello', five='goodbye'))]) 269 270 def test_run_class_cleanUp(self): 271 ordering = [] 272 blowUp = True 273 274 class TestableTest(unittest.TestCase): 275 @classmethod 276 def setUpClass(cls): 277 ordering.append('setUpClass') 278 cls.addClassCleanup(cleanup, ordering) 279 if blowUp: 280 raise Exception() 281 def testNothing(self): 282 ordering.append('test') 283 @classmethod 284 def tearDownClass(cls): 285 ordering.append('tearDownClass') 286 287 runTests(TestableTest) 288 self.assertEqual(ordering, ['setUpClass', 'cleanup_good']) 289 290 ordering = [] 291 blowUp = False 292 runTests(TestableTest) 293 self.assertEqual(ordering, 294 ['setUpClass', 'test', 'tearDownClass', 'cleanup_good']) 295 296 def test_run_class_cleanUp_without_tearDownClass(self): 297 ordering = [] 298 blowUp = True 299 300 class TestableTest(unittest.TestCase): 301 @classmethod 302 def setUpClass(cls): 303 ordering.append('setUpClass') 304 cls.addClassCleanup(cleanup, ordering) 305 if blowUp: 306 raise Exception() 307 def testNothing(self): 308 ordering.append('test') 309 @classmethod 310 @property 311 def tearDownClass(cls): 312 raise AttributeError 313 314 runTests(TestableTest) 315 self.assertEqual(ordering, ['setUpClass', 'cleanup_good']) 316 317 ordering = [] 318 blowUp = False 319 runTests(TestableTest) 320 self.assertEqual(ordering, 321 ['setUpClass', 'test', 'cleanup_good']) 322 323 def test_debug_executes_classCleanUp(self): 324 ordering = [] 325 blowUp = False 326 327 class TestableTest(unittest.TestCase): 328 @classmethod 329 def setUpClass(cls): 330 ordering.append('setUpClass') 331 cls.addClassCleanup(cleanup, ordering, blowUp=blowUp) 332 def testNothing(self): 333 ordering.append('test') 334 @classmethod 335 def tearDownClass(cls): 336 ordering.append('tearDownClass') 337 338 suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) 339 suite.debug() 340 self.assertEqual(ordering, 341 ['setUpClass', 'test', 'tearDownClass', 'cleanup_good']) 342 343 ordering = [] 344 blowUp = True 345 suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) 346 with self.assertRaises(Exception) as cm: 347 suite.debug() 348 self.assertEqual(str(cm.exception), 'CleanUpExc') 349 self.assertEqual(ordering, 350 ['setUpClass', 'test', 'tearDownClass', 'cleanup_exc']) 351 352 def test_debug_executes_classCleanUp_when_teardown_exception(self): 353 ordering = [] 354 blowUp = False 355 356 class TestableTest(unittest.TestCase): 357 @classmethod 358 def setUpClass(cls): 359 ordering.append('setUpClass') 360 cls.addClassCleanup(cleanup, ordering, blowUp=blowUp) 361 def testNothing(self): 362 ordering.append('test') 363 @classmethod 364 def tearDownClass(cls): 365 ordering.append('tearDownClass') 366 raise Exception('TearDownClassExc') 367 368 suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) 369 with self.assertRaises(Exception) as cm: 370 suite.debug() 371 self.assertEqual(str(cm.exception), 'TearDownClassExc') 372 self.assertEqual(ordering, ['setUpClass', 'test', 'tearDownClass']) 373 self.assertTrue(TestableTest._class_cleanups) 374 TestableTest._class_cleanups.clear() 375 376 ordering = [] 377 blowUp = True 378 suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) 379 with self.assertRaises(Exception) as cm: 380 suite.debug() 381 self.assertEqual(str(cm.exception), 'TearDownClassExc') 382 self.assertEqual(ordering, ['setUpClass', 'test', 'tearDownClass']) 383 self.assertTrue(TestableTest._class_cleanups) 384 TestableTest._class_cleanups.clear() 385 386 def test_doClassCleanups_with_errors_addClassCleanUp(self): 387 class TestableTest(unittest.TestCase): 388 def testNothing(self): 389 pass 390 391 def cleanup1(): 392 raise Exception('cleanup1') 393 394 def cleanup2(): 395 raise Exception('cleanup2') 396 397 TestableTest.addClassCleanup(cleanup1) 398 TestableTest.addClassCleanup(cleanup2) 399 with self.assertRaises(Exception) as e: 400 TestableTest.doClassCleanups() 401 self.assertEqual(e, 'cleanup1') 402 403 def test_with_errors_addCleanUp(self): 404 ordering = [] 405 class TestableTest(unittest.TestCase): 406 @classmethod 407 def setUpClass(cls): 408 ordering.append('setUpClass') 409 cls.addClassCleanup(cleanup, ordering) 410 def setUp(self): 411 ordering.append('setUp') 412 self.addCleanup(cleanup, ordering, blowUp=True) 413 def testNothing(self): 414 pass 415 @classmethod 416 def tearDownClass(cls): 417 ordering.append('tearDownClass') 418 419 result = runTests(TestableTest) 420 self.assertEqual(result.errors[0][1].splitlines()[-1], 421 'Exception: CleanUpExc') 422 self.assertEqual(ordering, 423 ['setUpClass', 'setUp', 'cleanup_exc', 424 'tearDownClass', 'cleanup_good']) 425 426 def test_run_with_errors_addClassCleanUp(self): 427 ordering = [] 428 class TestableTest(unittest.TestCase): 429 @classmethod 430 def setUpClass(cls): 431 ordering.append('setUpClass') 432 cls.addClassCleanup(cleanup, ordering, blowUp=True) 433 def setUp(self): 434 ordering.append('setUp') 435 self.addCleanup(cleanup, ordering) 436 def testNothing(self): 437 ordering.append('test') 438 @classmethod 439 def tearDownClass(cls): 440 ordering.append('tearDownClass') 441 442 result = runTests(TestableTest) 443 self.assertEqual(result.errors[0][1].splitlines()[-1], 444 'Exception: CleanUpExc') 445 self.assertEqual(ordering, 446 ['setUpClass', 'setUp', 'test', 'cleanup_good', 447 'tearDownClass', 'cleanup_exc']) 448 449 def test_with_errors_in_addClassCleanup_and_setUps(self): 450 ordering = [] 451 class_blow_up = False 452 method_blow_up = False 453 454 class TestableTest(unittest.TestCase): 455 @classmethod 456 def setUpClass(cls): 457 ordering.append('setUpClass') 458 cls.addClassCleanup(cleanup, ordering, blowUp=True) 459 if class_blow_up: 460 raise Exception('ClassExc') 461 def setUp(self): 462 ordering.append('setUp') 463 if method_blow_up: 464 raise Exception('MethodExc') 465 def testNothing(self): 466 ordering.append('test') 467 @classmethod 468 def tearDownClass(cls): 469 ordering.append('tearDownClass') 470 471 result = runTests(TestableTest) 472 self.assertEqual(result.errors[0][1].splitlines()[-1], 473 'Exception: CleanUpExc') 474 self.assertEqual(ordering, 475 ['setUpClass', 'setUp', 'test', 476 'tearDownClass', 'cleanup_exc']) 477 478 ordering = [] 479 class_blow_up = True 480 method_blow_up = False 481 result = runTests(TestableTest) 482 self.assertEqual(result.errors[0][1].splitlines()[-1], 483 'Exception: ClassExc') 484 self.assertEqual(result.errors[1][1].splitlines()[-1], 485 'Exception: CleanUpExc') 486 self.assertEqual(ordering, 487 ['setUpClass', 'cleanup_exc']) 488 489 ordering = [] 490 class_blow_up = False 491 method_blow_up = True 492 result = runTests(TestableTest) 493 self.assertEqual(result.errors[0][1].splitlines()[-1], 494 'Exception: MethodExc') 495 self.assertEqual(result.errors[1][1].splitlines()[-1], 496 'Exception: CleanUpExc') 497 self.assertEqual(ordering, 498 ['setUpClass', 'setUp', 'tearDownClass', 499 'cleanup_exc']) 500 501 def test_with_errors_in_tearDownClass(self): 502 ordering = [] 503 class TestableTest(unittest.TestCase): 504 @classmethod 505 def setUpClass(cls): 506 ordering.append('setUpClass') 507 cls.addClassCleanup(cleanup, ordering) 508 def testNothing(self): 509 ordering.append('test') 510 @classmethod 511 def tearDownClass(cls): 512 ordering.append('tearDownClass') 513 raise Exception('TearDownExc') 514 515 result = runTests(TestableTest) 516 self.assertEqual(result.errors[0][1].splitlines()[-1], 517 'Exception: TearDownExc') 518 self.assertEqual(ordering, 519 ['setUpClass', 'test', 'tearDownClass', 'cleanup_good']) 520 521 def test_enterClassContext(self): 522 class TestableTest(unittest.TestCase): 523 def testNothing(self): 524 pass 525 526 cleanups = [] 527 528 TestableTest.addClassCleanup(cleanups.append, 'cleanup1') 529 cm = TestCM(cleanups, 42) 530 self.assertEqual(TestableTest.enterClassContext(cm), 42) 531 TestableTest.addClassCleanup(cleanups.append, 'cleanup2') 532 533 TestableTest.doClassCleanups() 534 self.assertEqual(cleanups, ['enter', 'cleanup2', 'exit', 'cleanup1']) 535 536 def test_enterClassContext_arg_errors(self): 537 class TestableTest(unittest.TestCase): 538 def testNothing(self): 539 pass 540 541 with self.assertRaisesRegex(TypeError, 'the context manager'): 542 TestableTest.enterClassContext(LacksEnterAndExit()) 543 with self.assertRaisesRegex(TypeError, 'the context manager'): 544 TestableTest.enterClassContext(LacksEnter()) 545 with self.assertRaisesRegex(TypeError, 'the context manager'): 546 TestableTest.enterClassContext(LacksExit()) 547 548 self.assertEqual(TestableTest._class_cleanups, []) 549 550 def test_run_nested_test(self): 551 ordering = [] 552 553 class InnerTest(unittest.TestCase): 554 @classmethod 555 def setUpClass(cls): 556 ordering.append('inner setup') 557 cls.addClassCleanup(ordering.append, 'inner cleanup') 558 def test(self): 559 ordering.append('inner test') 560 561 class OuterTest(unittest.TestCase): 562 @classmethod 563 def setUpClass(cls): 564 ordering.append('outer setup') 565 cls.addClassCleanup(ordering.append, 'outer cleanup') 566 def test(self): 567 ordering.append('start outer test') 568 runTests(InnerTest) 569 ordering.append('end outer test') 570 571 runTests(OuterTest) 572 self.assertEqual(ordering, [ 573 'outer setup', 'start outer test', 574 'inner setup', 'inner test', 'inner cleanup', 575 'end outer test', 'outer cleanup']) 576 577 578class TestModuleCleanUp(unittest.TestCase): 579 def test_add_and_do_ModuleCleanup(self): 580 module_cleanups = [] 581 582 def module_cleanup1(*args, **kwargs): 583 module_cleanups.append((3, args, kwargs)) 584 585 def module_cleanup2(*args, **kwargs): 586 module_cleanups.append((4, args, kwargs)) 587 588 class Module(object): 589 unittest.addModuleCleanup(module_cleanup1, 1, 2, 3, 590 four='hello', five='goodbye') 591 unittest.addModuleCleanup(module_cleanup2) 592 593 self.assertEqual(unittest.case._module_cleanups, 594 [(module_cleanup1, (1, 2, 3), 595 dict(four='hello', five='goodbye')), 596 (module_cleanup2, (), {})]) 597 598 unittest.case.doModuleCleanups() 599 self.assertEqual(module_cleanups, [(4, (), {}), (3, (1, 2, 3), 600 dict(four='hello', five='goodbye'))]) 601 self.assertEqual(unittest.case._module_cleanups, []) 602 603 def test_doModuleCleanup_with_errors_in_addModuleCleanup(self): 604 module_cleanups = [] 605 606 def module_cleanup_good(*args, **kwargs): 607 module_cleanups.append((3, args, kwargs)) 608 609 def module_cleanup_bad(*args, **kwargs): 610 raise Exception('CleanUpExc') 611 612 class Module(object): 613 unittest.addModuleCleanup(module_cleanup_good, 1, 2, 3, 614 four='hello', five='goodbye') 615 unittest.addModuleCleanup(module_cleanup_bad) 616 self.assertEqual(unittest.case._module_cleanups, 617 [(module_cleanup_good, (1, 2, 3), 618 dict(four='hello', five='goodbye')), 619 (module_cleanup_bad, (), {})]) 620 with self.assertRaises(Exception) as e: 621 unittest.case.doModuleCleanups() 622 self.assertEqual(str(e.exception), 'CleanUpExc') 623 self.assertEqual(unittest.case._module_cleanups, []) 624 625 def test_addModuleCleanup_arg_errors(self): 626 cleanups = [] 627 def cleanup(*args, **kwargs): 628 cleanups.append((args, kwargs)) 629 630 class Module(object): 631 unittest.addModuleCleanup(cleanup, 1, 2, function='hello') 632 with self.assertRaises(TypeError): 633 unittest.addModuleCleanup(function=cleanup, arg='hello') 634 with self.assertRaises(TypeError): 635 unittest.addModuleCleanup() 636 unittest.case.doModuleCleanups() 637 self.assertEqual(cleanups, 638 [((1, 2), {'function': 'hello'})]) 639 640 def test_run_module_cleanUp(self): 641 blowUp = True 642 ordering = [] 643 class Module(object): 644 @staticmethod 645 def setUpModule(): 646 ordering.append('setUpModule') 647 unittest.addModuleCleanup(cleanup, ordering) 648 if blowUp: 649 raise Exception('setUpModule Exc') 650 @staticmethod 651 def tearDownModule(): 652 ordering.append('tearDownModule') 653 654 class TestableTest(unittest.TestCase): 655 @classmethod 656 def setUpClass(cls): 657 ordering.append('setUpClass') 658 def testNothing(self): 659 ordering.append('test') 660 @classmethod 661 def tearDownClass(cls): 662 ordering.append('tearDownClass') 663 664 TestableTest.__module__ = 'Module' 665 sys.modules['Module'] = Module 666 result = runTests(TestableTest) 667 self.assertEqual(ordering, ['setUpModule', 'cleanup_good']) 668 self.assertEqual(result.errors[0][1].splitlines()[-1], 669 'Exception: setUpModule Exc') 670 671 ordering = [] 672 blowUp = False 673 runTests(TestableTest) 674 self.assertEqual(ordering, 675 ['setUpModule', 'setUpClass', 'test', 'tearDownClass', 676 'tearDownModule', 'cleanup_good']) 677 self.assertEqual(unittest.case._module_cleanups, []) 678 679 def test_run_multiple_module_cleanUp(self): 680 blowUp = True 681 blowUp2 = False 682 ordering = [] 683 class Module1(object): 684 @staticmethod 685 def setUpModule(): 686 ordering.append('setUpModule') 687 unittest.addModuleCleanup(cleanup, ordering) 688 if blowUp: 689 raise Exception() 690 @staticmethod 691 def tearDownModule(): 692 ordering.append('tearDownModule') 693 694 class Module2(object): 695 @staticmethod 696 def setUpModule(): 697 ordering.append('setUpModule2') 698 unittest.addModuleCleanup(cleanup, ordering) 699 if blowUp2: 700 raise Exception() 701 @staticmethod 702 def tearDownModule(): 703 ordering.append('tearDownModule2') 704 705 class TestableTest(unittest.TestCase): 706 @classmethod 707 def setUpClass(cls): 708 ordering.append('setUpClass') 709 def testNothing(self): 710 ordering.append('test') 711 @classmethod 712 def tearDownClass(cls): 713 ordering.append('tearDownClass') 714 715 class TestableTest2(unittest.TestCase): 716 @classmethod 717 def setUpClass(cls): 718 ordering.append('setUpClass2') 719 def testNothing(self): 720 ordering.append('test2') 721 @classmethod 722 def tearDownClass(cls): 723 ordering.append('tearDownClass2') 724 725 TestableTest.__module__ = 'Module1' 726 sys.modules['Module1'] = Module1 727 TestableTest2.__module__ = 'Module2' 728 sys.modules['Module2'] = Module2 729 runTests(TestableTest, TestableTest2) 730 self.assertEqual(ordering, ['setUpModule', 'cleanup_good', 731 'setUpModule2', 'setUpClass2', 'test2', 732 'tearDownClass2', 'tearDownModule2', 733 'cleanup_good']) 734 ordering = [] 735 blowUp = False 736 blowUp2 = True 737 runTests(TestableTest, TestableTest2) 738 self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', 739 'tearDownClass', 'tearDownModule', 740 'cleanup_good', 'setUpModule2', 741 'cleanup_good']) 742 743 ordering = [] 744 blowUp = False 745 blowUp2 = False 746 runTests(TestableTest, TestableTest2) 747 self.assertEqual(ordering, 748 ['setUpModule', 'setUpClass', 'test', 'tearDownClass', 749 'tearDownModule', 'cleanup_good', 'setUpModule2', 750 'setUpClass2', 'test2', 'tearDownClass2', 751 'tearDownModule2', 'cleanup_good']) 752 self.assertEqual(unittest.case._module_cleanups, []) 753 754 def test_run_module_cleanUp_without_teardown(self): 755 ordering = [] 756 class Module(object): 757 @staticmethod 758 def setUpModule(): 759 ordering.append('setUpModule') 760 unittest.addModuleCleanup(cleanup, ordering) 761 762 class TestableTest(unittest.TestCase): 763 @classmethod 764 def setUpClass(cls): 765 ordering.append('setUpClass') 766 def testNothing(self): 767 ordering.append('test') 768 @classmethod 769 def tearDownClass(cls): 770 ordering.append('tearDownClass') 771 772 TestableTest.__module__ = 'Module' 773 sys.modules['Module'] = Module 774 runTests(TestableTest) 775 self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', 776 'tearDownClass', 'cleanup_good']) 777 self.assertEqual(unittest.case._module_cleanups, []) 778 779 def test_run_module_cleanUp_when_teardown_exception(self): 780 ordering = [] 781 class Module(object): 782 @staticmethod 783 def setUpModule(): 784 ordering.append('setUpModule') 785 unittest.addModuleCleanup(cleanup, ordering) 786 @staticmethod 787 def tearDownModule(): 788 ordering.append('tearDownModule') 789 raise Exception('CleanUpExc') 790 791 class TestableTest(unittest.TestCase): 792 @classmethod 793 def setUpClass(cls): 794 ordering.append('setUpClass') 795 def testNothing(self): 796 ordering.append('test') 797 @classmethod 798 def tearDownClass(cls): 799 ordering.append('tearDownClass') 800 801 TestableTest.__module__ = 'Module' 802 sys.modules['Module'] = Module 803 result = runTests(TestableTest) 804 self.assertEqual(result.errors[0][1].splitlines()[-1], 805 'Exception: CleanUpExc') 806 self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', 807 'tearDownClass', 'tearDownModule', 808 'cleanup_good']) 809 self.assertEqual(unittest.case._module_cleanups, []) 810 811 def test_debug_module_executes_cleanUp(self): 812 ordering = [] 813 blowUp = False 814 class Module(object): 815 @staticmethod 816 def setUpModule(): 817 ordering.append('setUpModule') 818 unittest.addModuleCleanup(cleanup, ordering, blowUp=blowUp) 819 @staticmethod 820 def tearDownModule(): 821 ordering.append('tearDownModule') 822 823 class TestableTest(unittest.TestCase): 824 @classmethod 825 def setUpClass(cls): 826 ordering.append('setUpClass') 827 def testNothing(self): 828 ordering.append('test') 829 @classmethod 830 def tearDownClass(cls): 831 ordering.append('tearDownClass') 832 833 TestableTest.__module__ = 'Module' 834 sys.modules['Module'] = Module 835 suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) 836 suite.debug() 837 self.assertEqual(ordering, 838 ['setUpModule', 'setUpClass', 'test', 'tearDownClass', 839 'tearDownModule', 'cleanup_good']) 840 self.assertEqual(unittest.case._module_cleanups, []) 841 842 ordering = [] 843 blowUp = True 844 suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) 845 with self.assertRaises(Exception) as cm: 846 suite.debug() 847 self.assertEqual(str(cm.exception), 'CleanUpExc') 848 self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', 849 'tearDownClass', 'tearDownModule', 'cleanup_exc']) 850 self.assertEqual(unittest.case._module_cleanups, []) 851 852 def test_debug_module_cleanUp_when_teardown_exception(self): 853 ordering = [] 854 blowUp = False 855 class Module(object): 856 @staticmethod 857 def setUpModule(): 858 ordering.append('setUpModule') 859 unittest.addModuleCleanup(cleanup, ordering, blowUp=blowUp) 860 @staticmethod 861 def tearDownModule(): 862 ordering.append('tearDownModule') 863 raise Exception('TearDownModuleExc') 864 865 class TestableTest(unittest.TestCase): 866 @classmethod 867 def setUpClass(cls): 868 ordering.append('setUpClass') 869 def testNothing(self): 870 ordering.append('test') 871 @classmethod 872 def tearDownClass(cls): 873 ordering.append('tearDownClass') 874 875 TestableTest.__module__ = 'Module' 876 sys.modules['Module'] = Module 877 suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) 878 with self.assertRaises(Exception) as cm: 879 suite.debug() 880 self.assertEqual(str(cm.exception), 'TearDownModuleExc') 881 self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', 882 'tearDownClass', 'tearDownModule']) 883 self.assertTrue(unittest.case._module_cleanups) 884 unittest.case._module_cleanups.clear() 885 886 ordering = [] 887 blowUp = True 888 suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) 889 with self.assertRaises(Exception) as cm: 890 suite.debug() 891 self.assertEqual(str(cm.exception), 'TearDownModuleExc') 892 self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', 893 'tearDownClass', 'tearDownModule']) 894 self.assertTrue(unittest.case._module_cleanups) 895 unittest.case._module_cleanups.clear() 896 897 def test_addClassCleanup_arg_errors(self): 898 cleanups = [] 899 def cleanup(*args, **kwargs): 900 cleanups.append((args, kwargs)) 901 902 class TestableTest(unittest.TestCase): 903 @classmethod 904 def setUpClass(cls): 905 cls.addClassCleanup(cleanup, 1, 2, function=3, cls=4) 906 with self.assertRaises(TypeError): 907 cls.addClassCleanup(function=cleanup, arg='hello') 908 def testNothing(self): 909 pass 910 911 with self.assertRaises(TypeError): 912 TestableTest.addClassCleanup() 913 with self.assertRaises(TypeError): 914 unittest.TestCase.addCleanup(cls=TestableTest(), function=cleanup) 915 runTests(TestableTest) 916 self.assertEqual(cleanups, 917 [((1, 2), {'function': 3, 'cls': 4})]) 918 919 def test_addCleanup_arg_errors(self): 920 cleanups = [] 921 def cleanup(*args, **kwargs): 922 cleanups.append((args, kwargs)) 923 924 class TestableTest(unittest.TestCase): 925 def setUp(self2): 926 self2.addCleanup(cleanup, 1, 2, function=3, self=4) 927 with self.assertRaises(TypeError): 928 self2.addCleanup(function=cleanup, arg='hello') 929 def testNothing(self): 930 pass 931 932 with self.assertRaises(TypeError): 933 TestableTest().addCleanup() 934 with self.assertRaises(TypeError): 935 unittest.TestCase.addCleanup(self=TestableTest(), function=cleanup) 936 runTests(TestableTest) 937 self.assertEqual(cleanups, 938 [((1, 2), {'function': 3, 'self': 4})]) 939 940 def test_with_errors_in_addClassCleanup(self): 941 ordering = [] 942 943 class Module(object): 944 @staticmethod 945 def setUpModule(): 946 ordering.append('setUpModule') 947 unittest.addModuleCleanup(cleanup, ordering) 948 @staticmethod 949 def tearDownModule(): 950 ordering.append('tearDownModule') 951 952 class TestableTest(unittest.TestCase): 953 @classmethod 954 def setUpClass(cls): 955 ordering.append('setUpClass') 956 cls.addClassCleanup(cleanup, ordering, blowUp=True) 957 def testNothing(self): 958 ordering.append('test') 959 @classmethod 960 def tearDownClass(cls): 961 ordering.append('tearDownClass') 962 963 TestableTest.__module__ = 'Module' 964 sys.modules['Module'] = Module 965 966 result = runTests(TestableTest) 967 self.assertEqual(result.errors[0][1].splitlines()[-1], 968 'Exception: CleanUpExc') 969 self.assertEqual(ordering, 970 ['setUpModule', 'setUpClass', 'test', 'tearDownClass', 971 'cleanup_exc', 'tearDownModule', 'cleanup_good']) 972 973 def test_with_errors_in_addCleanup(self): 974 ordering = [] 975 class Module(object): 976 @staticmethod 977 def setUpModule(): 978 ordering.append('setUpModule') 979 unittest.addModuleCleanup(cleanup, ordering) 980 @staticmethod 981 def tearDownModule(): 982 ordering.append('tearDownModule') 983 984 class TestableTest(unittest.TestCase): 985 def setUp(self): 986 ordering.append('setUp') 987 self.addCleanup(cleanup, ordering, blowUp=True) 988 def testNothing(self): 989 ordering.append('test') 990 def tearDown(self): 991 ordering.append('tearDown') 992 993 TestableTest.__module__ = 'Module' 994 sys.modules['Module'] = Module 995 996 result = runTests(TestableTest) 997 self.assertEqual(result.errors[0][1].splitlines()[-1], 998 'Exception: CleanUpExc') 999 self.assertEqual(ordering, 1000 ['setUpModule', 'setUp', 'test', 'tearDown', 1001 'cleanup_exc', 'tearDownModule', 'cleanup_good']) 1002 1003 def test_with_errors_in_addModuleCleanup_and_setUps(self): 1004 ordering = [] 1005 module_blow_up = False 1006 class_blow_up = False 1007 method_blow_up = False 1008 class Module(object): 1009 @staticmethod 1010 def setUpModule(): 1011 ordering.append('setUpModule') 1012 unittest.addModuleCleanup(cleanup, ordering, blowUp=True) 1013 if module_blow_up: 1014 raise Exception('ModuleExc') 1015 @staticmethod 1016 def tearDownModule(): 1017 ordering.append('tearDownModule') 1018 1019 class TestableTest(unittest.TestCase): 1020 @classmethod 1021 def setUpClass(cls): 1022 ordering.append('setUpClass') 1023 if class_blow_up: 1024 raise Exception('ClassExc') 1025 def setUp(self): 1026 ordering.append('setUp') 1027 if method_blow_up: 1028 raise Exception('MethodExc') 1029 def testNothing(self): 1030 ordering.append('test') 1031 @classmethod 1032 def tearDownClass(cls): 1033 ordering.append('tearDownClass') 1034 1035 TestableTest.__module__ = 'Module' 1036 sys.modules['Module'] = Module 1037 1038 result = runTests(TestableTest) 1039 self.assertEqual(result.errors[0][1].splitlines()[-1], 1040 'Exception: CleanUpExc') 1041 self.assertEqual(ordering, 1042 ['setUpModule', 'setUpClass', 'setUp', 'test', 1043 'tearDownClass', 'tearDownModule', 1044 'cleanup_exc']) 1045 1046 ordering = [] 1047 module_blow_up = True 1048 class_blow_up = False 1049 method_blow_up = False 1050 result = runTests(TestableTest) 1051 self.assertEqual(result.errors[0][1].splitlines()[-1], 1052 'Exception: ModuleExc') 1053 self.assertEqual(result.errors[1][1].splitlines()[-1], 1054 'Exception: CleanUpExc') 1055 self.assertEqual(ordering, ['setUpModule', 'cleanup_exc']) 1056 1057 ordering = [] 1058 module_blow_up = False 1059 class_blow_up = True 1060 method_blow_up = False 1061 result = runTests(TestableTest) 1062 self.assertEqual(result.errors[0][1].splitlines()[-1], 1063 'Exception: ClassExc') 1064 self.assertEqual(result.errors[1][1].splitlines()[-1], 1065 'Exception: CleanUpExc') 1066 self.assertEqual(ordering, ['setUpModule', 'setUpClass', 1067 'tearDownModule', 'cleanup_exc']) 1068 1069 ordering = [] 1070 module_blow_up = False 1071 class_blow_up = False 1072 method_blow_up = True 1073 result = runTests(TestableTest) 1074 self.assertEqual(result.errors[0][1].splitlines()[-1], 1075 'Exception: MethodExc') 1076 self.assertEqual(result.errors[1][1].splitlines()[-1], 1077 'Exception: CleanUpExc') 1078 self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'setUp', 1079 'tearDownClass', 'tearDownModule', 1080 'cleanup_exc']) 1081 1082 def test_module_cleanUp_with_multiple_classes(self): 1083 ordering =[] 1084 def cleanup1(): 1085 ordering.append('cleanup1') 1086 1087 def cleanup2(): 1088 ordering.append('cleanup2') 1089 1090 def cleanup3(): 1091 ordering.append('cleanup3') 1092 1093 class Module(object): 1094 @staticmethod 1095 def setUpModule(): 1096 ordering.append('setUpModule') 1097 unittest.addModuleCleanup(cleanup1) 1098 @staticmethod 1099 def tearDownModule(): 1100 ordering.append('tearDownModule') 1101 1102 class TestableTest(unittest.TestCase): 1103 def setUp(self): 1104 ordering.append('setUp') 1105 self.addCleanup(cleanup2) 1106 def testNothing(self): 1107 ordering.append('test') 1108 def tearDown(self): 1109 ordering.append('tearDown') 1110 1111 class OtherTestableTest(unittest.TestCase): 1112 def setUp(self): 1113 ordering.append('setUp2') 1114 self.addCleanup(cleanup3) 1115 def testNothing(self): 1116 ordering.append('test2') 1117 def tearDown(self): 1118 ordering.append('tearDown2') 1119 1120 TestableTest.__module__ = 'Module' 1121 OtherTestableTest.__module__ = 'Module' 1122 sys.modules['Module'] = Module 1123 runTests(TestableTest, OtherTestableTest) 1124 self.assertEqual(ordering, 1125 ['setUpModule', 'setUp', 'test', 'tearDown', 1126 'cleanup2', 'setUp2', 'test2', 'tearDown2', 1127 'cleanup3', 'tearDownModule', 'cleanup1']) 1128 1129 def test_enterModuleContext(self): 1130 cleanups = [] 1131 1132 unittest.addModuleCleanup(cleanups.append, 'cleanup1') 1133 cm = TestCM(cleanups, 42) 1134 self.assertEqual(unittest.enterModuleContext(cm), 42) 1135 unittest.addModuleCleanup(cleanups.append, 'cleanup2') 1136 1137 unittest.case.doModuleCleanups() 1138 self.assertEqual(cleanups, ['enter', 'cleanup2', 'exit', 'cleanup1']) 1139 1140 def test_enterModuleContext_arg_errors(self): 1141 class TestableTest(unittest.TestCase): 1142 def testNothing(self): 1143 pass 1144 1145 with self.assertRaisesRegex(TypeError, 'the context manager'): 1146 unittest.enterModuleContext(LacksEnterAndExit()) 1147 with self.assertRaisesRegex(TypeError, 'the context manager'): 1148 unittest.enterModuleContext(LacksEnter()) 1149 with self.assertRaisesRegex(TypeError, 'the context manager'): 1150 unittest.enterModuleContext(LacksExit()) 1151 1152 self.assertEqual(unittest.case._module_cleanups, []) 1153 1154 1155class Test_TextTestRunner(unittest.TestCase): 1156 """Tests for TextTestRunner.""" 1157 1158 def setUp(self): 1159 # clean the environment from pre-existing PYTHONWARNINGS to make 1160 # test_warnings results consistent 1161 self.pythonwarnings = os.environ.get('PYTHONWARNINGS') 1162 if self.pythonwarnings: 1163 del os.environ['PYTHONWARNINGS'] 1164 1165 def tearDown(self): 1166 # bring back pre-existing PYTHONWARNINGS if present 1167 if self.pythonwarnings: 1168 os.environ['PYTHONWARNINGS'] = self.pythonwarnings 1169 1170 def test_init(self): 1171 runner = unittest.TextTestRunner() 1172 self.assertFalse(runner.failfast) 1173 self.assertFalse(runner.buffer) 1174 self.assertEqual(runner.verbosity, 1) 1175 self.assertEqual(runner.warnings, None) 1176 self.assertTrue(runner.descriptions) 1177 self.assertEqual(runner.resultclass, unittest.TextTestResult) 1178 self.assertFalse(runner.tb_locals) 1179 1180 def test_multiple_inheritance(self): 1181 class AResult(unittest.TestResult): 1182 def __init__(self, stream, descriptions, verbosity): 1183 super(AResult, self).__init__(stream, descriptions, verbosity) 1184 1185 class ATextResult(unittest.TextTestResult, AResult): 1186 pass 1187 1188 # This used to raise an exception due to TextTestResult not passing 1189 # on arguments in its __init__ super call 1190 ATextResult(None, None, 1) 1191 1192 def testBufferAndFailfast(self): 1193 class Test(unittest.TestCase): 1194 def testFoo(self): 1195 pass 1196 result = unittest.TestResult() 1197 runner = unittest.TextTestRunner(stream=io.StringIO(), failfast=True, 1198 buffer=True) 1199 # Use our result object 1200 runner._makeResult = lambda: result 1201 runner.run(Test('testFoo')) 1202 1203 self.assertTrue(result.failfast) 1204 self.assertTrue(result.buffer) 1205 1206 def test_locals(self): 1207 runner = unittest.TextTestRunner(stream=io.StringIO(), tb_locals=True) 1208 result = runner.run(unittest.TestSuite()) 1209 self.assertEqual(True, result.tb_locals) 1210 1211 def testRunnerRegistersResult(self): 1212 class Test(unittest.TestCase): 1213 def testFoo(self): 1214 pass 1215 originalRegisterResult = unittest.runner.registerResult 1216 def cleanup(): 1217 unittest.runner.registerResult = originalRegisterResult 1218 self.addCleanup(cleanup) 1219 1220 result = unittest.TestResult() 1221 runner = unittest.TextTestRunner(stream=io.StringIO()) 1222 # Use our result object 1223 runner._makeResult = lambda: result 1224 1225 self.wasRegistered = 0 1226 def fakeRegisterResult(thisResult): 1227 self.wasRegistered += 1 1228 self.assertEqual(thisResult, result) 1229 unittest.runner.registerResult = fakeRegisterResult 1230 1231 runner.run(unittest.TestSuite()) 1232 self.assertEqual(self.wasRegistered, 1) 1233 1234 def test_works_with_result_without_startTestRun_stopTestRun(self): 1235 class OldTextResult(ResultWithNoStartTestRunStopTestRun): 1236 separator2 = '' 1237 def printErrors(self): 1238 pass 1239 1240 class Runner(unittest.TextTestRunner): 1241 def __init__(self): 1242 super(Runner, self).__init__(io.StringIO()) 1243 1244 def _makeResult(self): 1245 return OldTextResult() 1246 1247 runner = Runner() 1248 runner.run(unittest.TestSuite()) 1249 1250 def test_startTestRun_stopTestRun_called(self): 1251 class LoggingTextResult(LoggingResult): 1252 separator2 = '' 1253 def printErrors(self): 1254 pass 1255 1256 class LoggingRunner(unittest.TextTestRunner): 1257 def __init__(self, events): 1258 super(LoggingRunner, self).__init__(io.StringIO()) 1259 self._events = events 1260 1261 def _makeResult(self): 1262 return LoggingTextResult(self._events) 1263 1264 events = [] 1265 runner = LoggingRunner(events) 1266 runner.run(unittest.TestSuite()) 1267 expected = ['startTestRun', 'stopTestRun'] 1268 self.assertEqual(events, expected) 1269 1270 def test_pickle_unpickle(self): 1271 # Issue #7197: a TextTestRunner should be (un)pickleable. This is 1272 # required by test_multiprocessing under Windows (in verbose mode). 1273 stream = io.StringIO("foo") 1274 runner = unittest.TextTestRunner(stream) 1275 for protocol in range(2, pickle.HIGHEST_PROTOCOL + 1): 1276 s = pickle.dumps(runner, protocol) 1277 obj = pickle.loads(s) 1278 # StringIO objects never compare equal, a cheap test instead. 1279 self.assertEqual(obj.stream.getvalue(), stream.getvalue()) 1280 1281 def test_resultclass(self): 1282 def MockResultClass(*args): 1283 return args 1284 STREAM = object() 1285 DESCRIPTIONS = object() 1286 VERBOSITY = object() 1287 runner = unittest.TextTestRunner(STREAM, DESCRIPTIONS, VERBOSITY, 1288 resultclass=MockResultClass) 1289 self.assertEqual(runner.resultclass, MockResultClass) 1290 1291 expectedresult = (runner.stream, DESCRIPTIONS, VERBOSITY) 1292 self.assertEqual(runner._makeResult(), expectedresult) 1293 1294 @support.requires_subprocess() 1295 def test_warnings(self): 1296 """ 1297 Check that warnings argument of TextTestRunner correctly affects the 1298 behavior of the warnings. 1299 """ 1300 # see #10535 and the _test_warnings file for more information 1301 1302 def get_parse_out_err(p): 1303 return [b.splitlines() for b in p.communicate()] 1304 opts = dict(stdout=subprocess.PIPE, stderr=subprocess.PIPE, 1305 cwd=os.path.dirname(__file__)) 1306 ae_msg = b'Please use assertEqual instead.' 1307 at_msg = b'Please use assertTrue instead.' 1308 1309 # no args -> all the warnings are printed, unittest warnings only once 1310 p = subprocess.Popen([sys.executable, '-E', '_test_warnings.py'], **opts) 1311 with p: 1312 out, err = get_parse_out_err(p) 1313 self.assertIn(b'OK', err) 1314 # check that the total number of warnings in the output is correct 1315 self.assertEqual(len(out), 12) 1316 # check that the numbers of the different kind of warnings is correct 1317 for msg in [b'dw', b'iw', b'uw']: 1318 self.assertEqual(out.count(msg), 3) 1319 for msg in [ae_msg, at_msg, b'rw']: 1320 self.assertEqual(out.count(msg), 1) 1321 1322 args_list = ( 1323 # passing 'ignore' as warnings arg -> no warnings 1324 [sys.executable, '_test_warnings.py', 'ignore'], 1325 # -W doesn't affect the result if the arg is passed 1326 [sys.executable, '-Wa', '_test_warnings.py', 'ignore'], 1327 # -W affects the result if the arg is not passed 1328 [sys.executable, '-Wi', '_test_warnings.py'] 1329 ) 1330 # in all these cases no warnings are printed 1331 for args in args_list: 1332 p = subprocess.Popen(args, **opts) 1333 with p: 1334 out, err = get_parse_out_err(p) 1335 self.assertIn(b'OK', err) 1336 self.assertEqual(len(out), 0) 1337 1338 1339 # passing 'always' as warnings arg -> all the warnings printed, 1340 # unittest warnings only once 1341 p = subprocess.Popen([sys.executable, '_test_warnings.py', 'always'], 1342 **opts) 1343 with p: 1344 out, err = get_parse_out_err(p) 1345 self.assertIn(b'OK', err) 1346 self.assertEqual(len(out), 14) 1347 for msg in [b'dw', b'iw', b'uw', b'rw']: 1348 self.assertEqual(out.count(msg), 3) 1349 for msg in [ae_msg, at_msg]: 1350 self.assertEqual(out.count(msg), 1) 1351 1352 def testStdErrLookedUpAtInstantiationTime(self): 1353 # see issue 10786 1354 old_stderr = sys.stderr 1355 f = io.StringIO() 1356 sys.stderr = f 1357 try: 1358 runner = unittest.TextTestRunner() 1359 self.assertTrue(runner.stream.stream is f) 1360 finally: 1361 sys.stderr = old_stderr 1362 1363 def testSpecifiedStreamUsed(self): 1364 # see issue 10786 1365 f = io.StringIO() 1366 runner = unittest.TextTestRunner(f) 1367 self.assertTrue(runner.stream.stream is f) 1368 1369 1370if __name__ == "__main__": 1371 unittest.main() 1372