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