1import functools 2import sys 3import types 4import warnings 5 6import unittest 7 8class Test_TestLoader(unittest.TestCase): 9 10 ### Basic object tests 11 ################################################################ 12 13 def test___init__(self): 14 loader = unittest.TestLoader() 15 self.assertEqual([], loader.errors) 16 17 ### Tests for TestLoader.loadTestsFromTestCase 18 ################################################################ 19 20 # "Return a suite of all test cases contained in the TestCase-derived 21 # class testCaseClass" 22 def test_loadTestsFromTestCase(self): 23 class Foo(unittest.TestCase): 24 def test_1(self): pass 25 def test_2(self): pass 26 def foo_bar(self): pass 27 28 tests = unittest.TestSuite([Foo('test_1'), Foo('test_2')]) 29 30 loader = unittest.TestLoader() 31 self.assertEqual(loader.loadTestsFromTestCase(Foo), tests) 32 33 # "Return a suite of all test cases contained in the TestCase-derived 34 # class testCaseClass" 35 # 36 # Make sure it does the right thing even if no tests were found 37 def test_loadTestsFromTestCase__no_matches(self): 38 class Foo(unittest.TestCase): 39 def foo_bar(self): pass 40 41 empty_suite = unittest.TestSuite() 42 43 loader = unittest.TestLoader() 44 self.assertEqual(loader.loadTestsFromTestCase(Foo), empty_suite) 45 46 # "Return a suite of all test cases contained in the TestCase-derived 47 # class testCaseClass" 48 # 49 # What happens if loadTestsFromTestCase() is given an object 50 # that isn't a subclass of TestCase? Specifically, what happens 51 # if testCaseClass is a subclass of TestSuite? 52 # 53 # This is checked for specifically in the code, so we better add a 54 # test for it. 55 def test_loadTestsFromTestCase__TestSuite_subclass(self): 56 class NotATestCase(unittest.TestSuite): 57 pass 58 59 loader = unittest.TestLoader() 60 try: 61 loader.loadTestsFromTestCase(NotATestCase) 62 except TypeError: 63 pass 64 else: 65 self.fail('Should raise TypeError') 66 67 # "Return a suite of all test cases contained in the TestCase-derived 68 # class testCaseClass" 69 # 70 # Make sure loadTestsFromTestCase() picks up the default test method 71 # name (as specified by TestCase), even though the method name does 72 # not match the default TestLoader.testMethodPrefix string 73 def test_loadTestsFromTestCase__default_method_name(self): 74 class Foo(unittest.TestCase): 75 def runTest(self): 76 pass 77 78 loader = unittest.TestLoader() 79 # This has to be false for the test to succeed 80 self.assertFalse('runTest'.startswith(loader.testMethodPrefix)) 81 82 suite = loader.loadTestsFromTestCase(Foo) 83 self.assertIsInstance(suite, loader.suiteClass) 84 self.assertEqual(list(suite), [Foo('runTest')]) 85 86 ################################################################ 87 ### /Tests for TestLoader.loadTestsFromTestCase 88 89 ### Tests for TestLoader.loadTestsFromModule 90 ################################################################ 91 92 # "This method searches `module` for classes derived from TestCase" 93 def test_loadTestsFromModule__TestCase_subclass(self): 94 m = types.ModuleType('m') 95 class MyTestCase(unittest.TestCase): 96 def test(self): 97 pass 98 m.testcase_1 = MyTestCase 99 100 loader = unittest.TestLoader() 101 suite = loader.loadTestsFromModule(m) 102 self.assertIsInstance(suite, loader.suiteClass) 103 104 expected = [loader.suiteClass([MyTestCase('test')])] 105 self.assertEqual(list(suite), expected) 106 107 # "This method searches `module` for classes derived from TestCase" 108 # 109 # What happens if no tests are found (no TestCase instances)? 110 def test_loadTestsFromModule__no_TestCase_instances(self): 111 m = types.ModuleType('m') 112 113 loader = unittest.TestLoader() 114 suite = loader.loadTestsFromModule(m) 115 self.assertIsInstance(suite, loader.suiteClass) 116 self.assertEqual(list(suite), []) 117 118 # "This method searches `module` for classes derived from TestCase" 119 # 120 # What happens if no tests are found (TestCases instances, but no tests)? 121 def test_loadTestsFromModule__no_TestCase_tests(self): 122 m = types.ModuleType('m') 123 class MyTestCase(unittest.TestCase): 124 pass 125 m.testcase_1 = MyTestCase 126 127 loader = unittest.TestLoader() 128 suite = loader.loadTestsFromModule(m) 129 self.assertIsInstance(suite, loader.suiteClass) 130 131 self.assertEqual(list(suite), [loader.suiteClass()]) 132 133 # "This method searches `module` for classes derived from TestCase"s 134 # 135 # What happens if loadTestsFromModule() is given something other 136 # than a module? 137 # 138 # XXX Currently, it succeeds anyway. This flexibility 139 # should either be documented or loadTestsFromModule() should 140 # raise a TypeError 141 # 142 # XXX Certain people are using this behaviour. We'll add a test for it 143 def test_loadTestsFromModule__not_a_module(self): 144 class MyTestCase(unittest.TestCase): 145 def test(self): 146 pass 147 148 class NotAModule(object): 149 test_2 = MyTestCase 150 151 loader = unittest.TestLoader() 152 suite = loader.loadTestsFromModule(NotAModule) 153 154 reference = [unittest.TestSuite([MyTestCase('test')])] 155 self.assertEqual(list(suite), reference) 156 157 158 # Check that loadTestsFromModule honors a module 159 # with a load_tests function. 160 def test_loadTestsFromModule__load_tests(self): 161 m = types.ModuleType('m') 162 class MyTestCase(unittest.TestCase): 163 def test(self): 164 pass 165 m.testcase_1 = MyTestCase 166 167 load_tests_args = [] 168 def load_tests(loader, tests, pattern): 169 self.assertIsInstance(tests, unittest.TestSuite) 170 load_tests_args.extend((loader, tests, pattern)) 171 return tests 172 m.load_tests = load_tests 173 174 loader = unittest.TestLoader() 175 suite = loader.loadTestsFromModule(m) 176 self.assertIsInstance(suite, unittest.TestSuite) 177 self.assertEqual(load_tests_args, [loader, suite, None]) 178 179 # In Python 3.11, the undocumented and unofficial use_load_tests has 180 # been removed. 181 with self.assertRaises(TypeError): 182 loader.loadTestsFromModule(m, False) 183 with self.assertRaises(TypeError): 184 loader.loadTestsFromModule(m, use_load_tests=False) 185 186 def test_loadTestsFromModule__pattern(self): 187 m = types.ModuleType('m') 188 class MyTestCase(unittest.TestCase): 189 def test(self): 190 pass 191 m.testcase_1 = MyTestCase 192 193 load_tests_args = [] 194 def load_tests(loader, tests, pattern): 195 self.assertIsInstance(tests, unittest.TestSuite) 196 load_tests_args.extend((loader, tests, pattern)) 197 return tests 198 m.load_tests = load_tests 199 200 loader = unittest.TestLoader() 201 suite = loader.loadTestsFromModule(m, pattern='testme.*') 202 self.assertIsInstance(suite, unittest.TestSuite) 203 self.assertEqual(load_tests_args, [loader, suite, 'testme.*']) 204 205 def test_loadTestsFromModule__faulty_load_tests(self): 206 m = types.ModuleType('m') 207 208 def load_tests(loader, tests, pattern): 209 raise TypeError('some failure') 210 m.load_tests = load_tests 211 212 loader = unittest.TestLoader() 213 suite = loader.loadTestsFromModule(m) 214 self.assertIsInstance(suite, unittest.TestSuite) 215 self.assertEqual(suite.countTestCases(), 1) 216 # Errors loading the suite are also captured for introspection. 217 self.assertNotEqual([], loader.errors) 218 self.assertEqual(1, len(loader.errors)) 219 error = loader.errors[0] 220 self.assertTrue( 221 'Failed to call load_tests:' in error, 222 'missing error string in %r' % error) 223 test = list(suite)[0] 224 225 self.assertRaisesRegex(TypeError, "some failure", test.m) 226 227 ################################################################ 228 ### /Tests for TestLoader.loadTestsFromModule() 229 230 ### Tests for TestLoader.loadTestsFromName() 231 ################################################################ 232 233 # "The specifier name is a ``dotted name'' that may resolve either to 234 # a module, a test case class, a TestSuite instance, a test method 235 # within a test case class, or a callable object which returns a 236 # TestCase or TestSuite instance." 237 # 238 # Is ValueError raised in response to an empty name? 239 def test_loadTestsFromName__empty_name(self): 240 loader = unittest.TestLoader() 241 242 try: 243 loader.loadTestsFromName('') 244 except ValueError as e: 245 self.assertEqual(str(e), "Empty module name") 246 else: 247 self.fail("TestLoader.loadTestsFromName failed to raise ValueError") 248 249 # "The specifier name is a ``dotted name'' that may resolve either to 250 # a module, a test case class, a TestSuite instance, a test method 251 # within a test case class, or a callable object which returns a 252 # TestCase or TestSuite instance." 253 # 254 # What happens when the name contains invalid characters? 255 def test_loadTestsFromName__malformed_name(self): 256 loader = unittest.TestLoader() 257 258 suite = loader.loadTestsFromName('abc () //') 259 error, test = self.check_deferred_error(loader, suite) 260 expected = "Failed to import test module: abc () //" 261 expected_regex = r"Failed to import test module: abc \(\) //" 262 self.assertIn( 263 expected, error, 264 'missing error string in %r' % error) 265 self.assertRaisesRegex( 266 ImportError, expected_regex, getattr(test, 'abc () //')) 267 268 # "The specifier name is a ``dotted name'' that may resolve ... to a 269 # module" 270 # 271 # What happens when a module by that name can't be found? 272 def test_loadTestsFromName__unknown_module_name(self): 273 loader = unittest.TestLoader() 274 275 suite = loader.loadTestsFromName('sdasfasfasdf') 276 expected = "No module named 'sdasfasfasdf'" 277 error, test = self.check_deferred_error(loader, suite) 278 self.assertIn( 279 expected, error, 280 'missing error string in %r' % error) 281 self.assertRaisesRegex(ImportError, expected, test.sdasfasfasdf) 282 283 # "The specifier name is a ``dotted name'' that may resolve either to 284 # a module, a test case class, a TestSuite instance, a test method 285 # within a test case class, or a callable object which returns a 286 # TestCase or TestSuite instance." 287 # 288 # What happens when the module is found, but the attribute isn't? 289 def test_loadTestsFromName__unknown_attr_name_on_module(self): 290 loader = unittest.TestLoader() 291 292 suite = loader.loadTestsFromName('unittest.loader.sdasfasfasdf') 293 expected = "module 'unittest.loader' has no attribute 'sdasfasfasdf'" 294 error, test = self.check_deferred_error(loader, suite) 295 self.assertIn( 296 expected, error, 297 'missing error string in %r' % error) 298 self.assertRaisesRegex(AttributeError, expected, test.sdasfasfasdf) 299 300 # "The specifier name is a ``dotted name'' that may resolve either to 301 # a module, a test case class, a TestSuite instance, a test method 302 # within a test case class, or a callable object which returns a 303 # TestCase or TestSuite instance." 304 # 305 # What happens when the module is found, but the attribute isn't? 306 def test_loadTestsFromName__unknown_attr_name_on_package(self): 307 loader = unittest.TestLoader() 308 309 suite = loader.loadTestsFromName('unittest.sdasfasfasdf') 310 expected = "No module named 'unittest.sdasfasfasdf'" 311 error, test = self.check_deferred_error(loader, suite) 312 self.assertIn( 313 expected, error, 314 'missing error string in %r' % error) 315 self.assertRaisesRegex(ImportError, expected, test.sdasfasfasdf) 316 317 # "The specifier name is a ``dotted name'' that may resolve either to 318 # a module, a test case class, a TestSuite instance, a test method 319 # within a test case class, or a callable object which returns a 320 # TestCase or TestSuite instance." 321 # 322 # What happens when we provide the module, but the attribute can't be 323 # found? 324 def test_loadTestsFromName__relative_unknown_name(self): 325 loader = unittest.TestLoader() 326 327 suite = loader.loadTestsFromName('sdasfasfasdf', unittest) 328 expected = "module 'unittest' has no attribute 'sdasfasfasdf'" 329 error, test = self.check_deferred_error(loader, suite) 330 self.assertIn( 331 expected, error, 332 'missing error string in %r' % error) 333 self.assertRaisesRegex(AttributeError, expected, test.sdasfasfasdf) 334 335 # "The specifier name is a ``dotted name'' that may resolve either to 336 # a module, a test case class, a TestSuite instance, a test method 337 # within a test case class, or a callable object which returns a 338 # TestCase or TestSuite instance." 339 # ... 340 # "The method optionally resolves name relative to the given module" 341 # 342 # Does loadTestsFromName raise ValueError when passed an empty 343 # name relative to a provided module? 344 # 345 # XXX Should probably raise a ValueError instead of an AttributeError 346 def test_loadTestsFromName__relative_empty_name(self): 347 loader = unittest.TestLoader() 348 349 suite = loader.loadTestsFromName('', unittest) 350 error, test = self.check_deferred_error(loader, suite) 351 expected = "has no attribute ''" 352 self.assertIn( 353 expected, error, 354 'missing error string in %r' % error) 355 self.assertRaisesRegex(AttributeError, expected, getattr(test, '')) 356 357 # "The specifier name is a ``dotted name'' that may resolve either to 358 # a module, a test case class, a TestSuite instance, a test method 359 # within a test case class, or a callable object which returns a 360 # TestCase or TestSuite instance." 361 # ... 362 # "The method optionally resolves name relative to the given module" 363 # 364 # What happens when an impossible name is given, relative to the provided 365 # `module`? 366 def test_loadTestsFromName__relative_malformed_name(self): 367 loader = unittest.TestLoader() 368 369 # XXX Should this raise AttributeError or ValueError? 370 suite = loader.loadTestsFromName('abc () //', unittest) 371 error, test = self.check_deferred_error(loader, suite) 372 expected = "module 'unittest' has no attribute 'abc () //'" 373 expected_regex = r"module 'unittest' has no attribute 'abc \(\) //'" 374 self.assertIn( 375 expected, error, 376 'missing error string in %r' % error) 377 self.assertRaisesRegex( 378 AttributeError, expected_regex, getattr(test, 'abc () //')) 379 380 # "The method optionally resolves name relative to the given module" 381 # 382 # Does loadTestsFromName raise TypeError when the `module` argument 383 # isn't a module object? 384 # 385 # XXX Accepts the not-a-module object, ignoring the object's type 386 # This should raise an exception or the method name should be changed 387 # 388 # XXX Some people are relying on this, so keep it for now 389 def test_loadTestsFromName__relative_not_a_module(self): 390 class MyTestCase(unittest.TestCase): 391 def test(self): 392 pass 393 394 class NotAModule(object): 395 test_2 = MyTestCase 396 397 loader = unittest.TestLoader() 398 suite = loader.loadTestsFromName('test_2', NotAModule) 399 400 reference = [MyTestCase('test')] 401 self.assertEqual(list(suite), reference) 402 403 # "The specifier name is a ``dotted name'' that may resolve either to 404 # a module, a test case class, a TestSuite instance, a test method 405 # within a test case class, or a callable object which returns a 406 # TestCase or TestSuite instance." 407 # 408 # Does it raise an exception if the name resolves to an invalid 409 # object? 410 def test_loadTestsFromName__relative_bad_object(self): 411 m = types.ModuleType('m') 412 m.testcase_1 = object() 413 414 loader = unittest.TestLoader() 415 try: 416 loader.loadTestsFromName('testcase_1', m) 417 except TypeError: 418 pass 419 else: 420 self.fail("Should have raised TypeError") 421 422 # "The specifier name is a ``dotted name'' that may 423 # resolve either to ... a test case class" 424 def test_loadTestsFromName__relative_TestCase_subclass(self): 425 m = types.ModuleType('m') 426 class MyTestCase(unittest.TestCase): 427 def test(self): 428 pass 429 m.testcase_1 = MyTestCase 430 431 loader = unittest.TestLoader() 432 suite = loader.loadTestsFromName('testcase_1', m) 433 self.assertIsInstance(suite, loader.suiteClass) 434 self.assertEqual(list(suite), [MyTestCase('test')]) 435 436 # "The specifier name is a ``dotted name'' that may resolve either to 437 # a module, a test case class, a TestSuite instance, a test method 438 # within a test case class, or a callable object which returns a 439 # TestCase or TestSuite instance." 440 def test_loadTestsFromName__relative_TestSuite(self): 441 m = types.ModuleType('m') 442 class MyTestCase(unittest.TestCase): 443 def test(self): 444 pass 445 m.testsuite = unittest.TestSuite([MyTestCase('test')]) 446 447 loader = unittest.TestLoader() 448 suite = loader.loadTestsFromName('testsuite', m) 449 self.assertIsInstance(suite, loader.suiteClass) 450 451 self.assertEqual(list(suite), [MyTestCase('test')]) 452 453 # "The specifier name is a ``dotted name'' that may resolve ... to 454 # ... a test method within a test case class" 455 def test_loadTestsFromName__relative_testmethod(self): 456 m = types.ModuleType('m') 457 class MyTestCase(unittest.TestCase): 458 def test(self): 459 pass 460 m.testcase_1 = MyTestCase 461 462 loader = unittest.TestLoader() 463 suite = loader.loadTestsFromName('testcase_1.test', m) 464 self.assertIsInstance(suite, loader.suiteClass) 465 466 self.assertEqual(list(suite), [MyTestCase('test')]) 467 468 # "The specifier name is a ``dotted name'' that may resolve either to 469 # a module, a test case class, a TestSuite instance, a test method 470 # within a test case class, or a callable object which returns a 471 # TestCase or TestSuite instance." 472 # 473 # Does loadTestsFromName() raise the proper exception when trying to 474 # resolve "a test method within a test case class" that doesn't exist 475 # for the given name (relative to a provided module)? 476 def test_loadTestsFromName__relative_invalid_testmethod(self): 477 m = types.ModuleType('m') 478 class MyTestCase(unittest.TestCase): 479 def test(self): 480 pass 481 m.testcase_1 = MyTestCase 482 483 loader = unittest.TestLoader() 484 suite = loader.loadTestsFromName('testcase_1.testfoo', m) 485 expected = "type object 'MyTestCase' has no attribute 'testfoo'" 486 error, test = self.check_deferred_error(loader, suite) 487 self.assertIn( 488 expected, error, 489 'missing error string in %r' % error) 490 self.assertRaisesRegex(AttributeError, expected, test.testfoo) 491 492 # "The specifier name is a ``dotted name'' that may resolve ... to 493 # ... a callable object which returns a ... TestSuite instance" 494 def test_loadTestsFromName__callable__TestSuite(self): 495 m = types.ModuleType('m') 496 testcase_1 = unittest.FunctionTestCase(lambda: None) 497 testcase_2 = unittest.FunctionTestCase(lambda: None) 498 def return_TestSuite(): 499 return unittest.TestSuite([testcase_1, testcase_2]) 500 m.return_TestSuite = return_TestSuite 501 502 loader = unittest.TestLoader() 503 suite = loader.loadTestsFromName('return_TestSuite', m) 504 self.assertIsInstance(suite, loader.suiteClass) 505 self.assertEqual(list(suite), [testcase_1, testcase_2]) 506 507 # "The specifier name is a ``dotted name'' that may resolve ... to 508 # ... a callable object which returns a TestCase ... instance" 509 def test_loadTestsFromName__callable__TestCase_instance(self): 510 m = types.ModuleType('m') 511 testcase_1 = unittest.FunctionTestCase(lambda: None) 512 def return_TestCase(): 513 return testcase_1 514 m.return_TestCase = return_TestCase 515 516 loader = unittest.TestLoader() 517 suite = loader.loadTestsFromName('return_TestCase', m) 518 self.assertIsInstance(suite, loader.suiteClass) 519 self.assertEqual(list(suite), [testcase_1]) 520 521 # "The specifier name is a ``dotted name'' that may resolve ... to 522 # ... a callable object which returns a TestCase ... instance" 523 #***************************************************************** 524 #Override the suiteClass attribute to ensure that the suiteClass 525 #attribute is used 526 def test_loadTestsFromName__callable__TestCase_instance_ProperSuiteClass(self): 527 class SubTestSuite(unittest.TestSuite): 528 pass 529 m = types.ModuleType('m') 530 testcase_1 = unittest.FunctionTestCase(lambda: None) 531 def return_TestCase(): 532 return testcase_1 533 m.return_TestCase = return_TestCase 534 535 loader = unittest.TestLoader() 536 loader.suiteClass = SubTestSuite 537 suite = loader.loadTestsFromName('return_TestCase', m) 538 self.assertIsInstance(suite, loader.suiteClass) 539 self.assertEqual(list(suite), [testcase_1]) 540 541 # "The specifier name is a ``dotted name'' that may resolve ... to 542 # ... a test method within a test case class" 543 #***************************************************************** 544 #Override the suiteClass attribute to ensure that the suiteClass 545 #attribute is used 546 def test_loadTestsFromName__relative_testmethod_ProperSuiteClass(self): 547 class SubTestSuite(unittest.TestSuite): 548 pass 549 m = types.ModuleType('m') 550 class MyTestCase(unittest.TestCase): 551 def test(self): 552 pass 553 m.testcase_1 = MyTestCase 554 555 loader = unittest.TestLoader() 556 loader.suiteClass=SubTestSuite 557 suite = loader.loadTestsFromName('testcase_1.test', m) 558 self.assertIsInstance(suite, loader.suiteClass) 559 560 self.assertEqual(list(suite), [MyTestCase('test')]) 561 562 # "The specifier name is a ``dotted name'' that may resolve ... to 563 # ... a callable object which returns a TestCase or TestSuite instance" 564 # 565 # What happens if the callable returns something else? 566 def test_loadTestsFromName__callable__wrong_type(self): 567 m = types.ModuleType('m') 568 def return_wrong(): 569 return 6 570 m.return_wrong = return_wrong 571 572 loader = unittest.TestLoader() 573 try: 574 suite = loader.loadTestsFromName('return_wrong', m) 575 except TypeError: 576 pass 577 else: 578 self.fail("TestLoader.loadTestsFromName failed to raise TypeError") 579 580 # "The specifier can refer to modules and packages which have not been 581 # imported; they will be imported as a side-effect" 582 def test_loadTestsFromName__module_not_loaded(self): 583 # We're going to try to load this module as a side-effect, so it 584 # better not be loaded before we try. 585 # 586 module_name = 'unittest.test.dummy' 587 sys.modules.pop(module_name, None) 588 589 loader = unittest.TestLoader() 590 try: 591 suite = loader.loadTestsFromName(module_name) 592 593 self.assertIsInstance(suite, loader.suiteClass) 594 self.assertEqual(list(suite), []) 595 596 # module should now be loaded, thanks to loadTestsFromName() 597 self.assertIn(module_name, sys.modules) 598 finally: 599 if module_name in sys.modules: 600 del sys.modules[module_name] 601 602 ################################################################ 603 ### Tests for TestLoader.loadTestsFromName() 604 605 ### Tests for TestLoader.loadTestsFromNames() 606 ################################################################ 607 608 def check_deferred_error(self, loader, suite): 609 """Helper function for checking that errors in loading are reported. 610 611 :param loader: A loader with some errors. 612 :param suite: A suite that should have a late bound error. 613 :return: The first error message from the loader and the test object 614 from the suite. 615 """ 616 self.assertIsInstance(suite, unittest.TestSuite) 617 self.assertEqual(suite.countTestCases(), 1) 618 # Errors loading the suite are also captured for introspection. 619 self.assertNotEqual([], loader.errors) 620 self.assertEqual(1, len(loader.errors)) 621 error = loader.errors[0] 622 test = list(suite)[0] 623 return error, test 624 625 # "Similar to loadTestsFromName(), but takes a sequence of names rather 626 # than a single name." 627 # 628 # What happens if that sequence of names is empty? 629 def test_loadTestsFromNames__empty_name_list(self): 630 loader = unittest.TestLoader() 631 632 suite = loader.loadTestsFromNames([]) 633 self.assertIsInstance(suite, loader.suiteClass) 634 self.assertEqual(list(suite), []) 635 636 # "Similar to loadTestsFromName(), but takes a sequence of names rather 637 # than a single name." 638 # ... 639 # "The method optionally resolves name relative to the given module" 640 # 641 # What happens if that sequence of names is empty? 642 # 643 # XXX Should this raise a ValueError or just return an empty TestSuite? 644 def test_loadTestsFromNames__relative_empty_name_list(self): 645 loader = unittest.TestLoader() 646 647 suite = loader.loadTestsFromNames([], unittest) 648 self.assertIsInstance(suite, loader.suiteClass) 649 self.assertEqual(list(suite), []) 650 651 # "The specifier name is a ``dotted name'' that may resolve either to 652 # a module, a test case class, a TestSuite instance, a test method 653 # within a test case class, or a callable object which returns a 654 # TestCase or TestSuite instance." 655 # 656 # Is ValueError raised in response to an empty name? 657 def test_loadTestsFromNames__empty_name(self): 658 loader = unittest.TestLoader() 659 660 try: 661 loader.loadTestsFromNames(['']) 662 except ValueError as e: 663 self.assertEqual(str(e), "Empty module name") 664 else: 665 self.fail("TestLoader.loadTestsFromNames failed to raise ValueError") 666 667 # "The specifier name is a ``dotted name'' that may resolve either to 668 # a module, a test case class, a TestSuite instance, a test method 669 # within a test case class, or a callable object which returns a 670 # TestCase or TestSuite instance." 671 # 672 # What happens when presented with an impossible module name? 673 def test_loadTestsFromNames__malformed_name(self): 674 loader = unittest.TestLoader() 675 676 # XXX Should this raise ValueError or ImportError? 677 suite = loader.loadTestsFromNames(['abc () //']) 678 error, test = self.check_deferred_error(loader, list(suite)[0]) 679 expected = "Failed to import test module: abc () //" 680 expected_regex = r"Failed to import test module: abc \(\) //" 681 self.assertIn( 682 expected, error, 683 'missing error string in %r' % error) 684 self.assertRaisesRegex( 685 ImportError, expected_regex, getattr(test, 'abc () //')) 686 687 # "The specifier name is a ``dotted name'' that may resolve either to 688 # a module, a test case class, a TestSuite instance, a test method 689 # within a test case class, or a callable object which returns a 690 # TestCase or TestSuite instance." 691 # 692 # What happens when no module can be found for the given name? 693 def test_loadTestsFromNames__unknown_module_name(self): 694 loader = unittest.TestLoader() 695 696 suite = loader.loadTestsFromNames(['sdasfasfasdf']) 697 error, test = self.check_deferred_error(loader, list(suite)[0]) 698 expected = "Failed to import test module: sdasfasfasdf" 699 self.assertIn( 700 expected, error, 701 'missing error string in %r' % error) 702 self.assertRaisesRegex(ImportError, expected, test.sdasfasfasdf) 703 704 # "The specifier name is a ``dotted name'' that may resolve either to 705 # a module, a test case class, a TestSuite instance, a test method 706 # within a test case class, or a callable object which returns a 707 # TestCase or TestSuite instance." 708 # 709 # What happens when the module can be found, but not the attribute? 710 def test_loadTestsFromNames__unknown_attr_name(self): 711 loader = unittest.TestLoader() 712 713 suite = loader.loadTestsFromNames( 714 ['unittest.loader.sdasfasfasdf', 'unittest.test.dummy']) 715 error, test = self.check_deferred_error(loader, list(suite)[0]) 716 expected = "module 'unittest.loader' has no attribute 'sdasfasfasdf'" 717 self.assertIn( 718 expected, error, 719 'missing error string in %r' % error) 720 self.assertRaisesRegex(AttributeError, expected, test.sdasfasfasdf) 721 722 # "The specifier name is a ``dotted name'' that may resolve either to 723 # a module, a test case class, a TestSuite instance, a test method 724 # within a test case class, or a callable object which returns a 725 # TestCase or TestSuite instance." 726 # ... 727 # "The method optionally resolves name relative to the given module" 728 # 729 # What happens when given an unknown attribute on a specified `module` 730 # argument? 731 def test_loadTestsFromNames__unknown_name_relative_1(self): 732 loader = unittest.TestLoader() 733 734 suite = loader.loadTestsFromNames(['sdasfasfasdf'], unittest) 735 error, test = self.check_deferred_error(loader, list(suite)[0]) 736 expected = "module 'unittest' has no attribute 'sdasfasfasdf'" 737 self.assertIn( 738 expected, error, 739 'missing error string in %r' % error) 740 self.assertRaisesRegex(AttributeError, expected, test.sdasfasfasdf) 741 742 # "The specifier name is a ``dotted name'' that may resolve either to 743 # a module, a test case class, a TestSuite instance, a test method 744 # within a test case class, or a callable object which returns a 745 # TestCase or TestSuite instance." 746 # ... 747 # "The method optionally resolves name relative to the given module" 748 # 749 # Do unknown attributes (relative to a provided module) still raise an 750 # exception even in the presence of valid attribute names? 751 def test_loadTestsFromNames__unknown_name_relative_2(self): 752 loader = unittest.TestLoader() 753 754 suite = loader.loadTestsFromNames(['TestCase', 'sdasfasfasdf'], unittest) 755 error, test = self.check_deferred_error(loader, list(suite)[1]) 756 expected = "module 'unittest' has no attribute 'sdasfasfasdf'" 757 self.assertIn( 758 expected, error, 759 'missing error string in %r' % error) 760 self.assertRaisesRegex(AttributeError, expected, test.sdasfasfasdf) 761 762 # "The specifier name is a ``dotted name'' that may resolve either to 763 # a module, a test case class, a TestSuite instance, a test method 764 # within a test case class, or a callable object which returns a 765 # TestCase or TestSuite instance." 766 # ... 767 # "The method optionally resolves name relative to the given module" 768 # 769 # What happens when faced with the empty string? 770 # 771 # XXX This currently raises AttributeError, though ValueError is probably 772 # more appropriate 773 def test_loadTestsFromNames__relative_empty_name(self): 774 loader = unittest.TestLoader() 775 776 suite = loader.loadTestsFromNames([''], unittest) 777 error, test = self.check_deferred_error(loader, list(suite)[0]) 778 expected = "has no attribute ''" 779 self.assertIn( 780 expected, error, 781 'missing error string in %r' % error) 782 self.assertRaisesRegex(AttributeError, expected, getattr(test, '')) 783 784 # "The specifier name is a ``dotted name'' that may resolve either to 785 # a module, a test case class, a TestSuite instance, a test method 786 # within a test case class, or a callable object which returns a 787 # TestCase or TestSuite instance." 788 # ... 789 # "The method optionally resolves name relative to the given module" 790 # 791 # What happens when presented with an impossible attribute name? 792 def test_loadTestsFromNames__relative_malformed_name(self): 793 loader = unittest.TestLoader() 794 795 # XXX Should this raise AttributeError or ValueError? 796 suite = loader.loadTestsFromNames(['abc () //'], unittest) 797 error, test = self.check_deferred_error(loader, list(suite)[0]) 798 expected = "module 'unittest' has no attribute 'abc () //'" 799 expected_regex = r"module 'unittest' has no attribute 'abc \(\) //'" 800 self.assertIn( 801 expected, error, 802 'missing error string in %r' % error) 803 self.assertRaisesRegex( 804 AttributeError, expected_regex, getattr(test, 'abc () //')) 805 806 # "The method optionally resolves name relative to the given module" 807 # 808 # Does loadTestsFromNames() make sure the provided `module` is in fact 809 # a module? 810 # 811 # XXX This validation is currently not done. This flexibility should 812 # either be documented or a TypeError should be raised. 813 def test_loadTestsFromNames__relative_not_a_module(self): 814 class MyTestCase(unittest.TestCase): 815 def test(self): 816 pass 817 818 class NotAModule(object): 819 test_2 = MyTestCase 820 821 loader = unittest.TestLoader() 822 suite = loader.loadTestsFromNames(['test_2'], NotAModule) 823 824 reference = [unittest.TestSuite([MyTestCase('test')])] 825 self.assertEqual(list(suite), reference) 826 827 # "The specifier name is a ``dotted name'' that may resolve either to 828 # a module, a test case class, a TestSuite instance, a test method 829 # within a test case class, or a callable object which returns a 830 # TestCase or TestSuite instance." 831 # 832 # Does it raise an exception if the name resolves to an invalid 833 # object? 834 def test_loadTestsFromNames__relative_bad_object(self): 835 m = types.ModuleType('m') 836 m.testcase_1 = object() 837 838 loader = unittest.TestLoader() 839 try: 840 loader.loadTestsFromNames(['testcase_1'], m) 841 except TypeError: 842 pass 843 else: 844 self.fail("Should have raised TypeError") 845 846 # "The specifier name is a ``dotted name'' that may resolve ... to 847 # ... a test case class" 848 def test_loadTestsFromNames__relative_TestCase_subclass(self): 849 m = types.ModuleType('m') 850 class MyTestCase(unittest.TestCase): 851 def test(self): 852 pass 853 m.testcase_1 = MyTestCase 854 855 loader = unittest.TestLoader() 856 suite = loader.loadTestsFromNames(['testcase_1'], m) 857 self.assertIsInstance(suite, loader.suiteClass) 858 859 expected = loader.suiteClass([MyTestCase('test')]) 860 self.assertEqual(list(suite), [expected]) 861 862 # "The specifier name is a ``dotted name'' that may resolve ... to 863 # ... a TestSuite instance" 864 def test_loadTestsFromNames__relative_TestSuite(self): 865 m = types.ModuleType('m') 866 class MyTestCase(unittest.TestCase): 867 def test(self): 868 pass 869 m.testsuite = unittest.TestSuite([MyTestCase('test')]) 870 871 loader = unittest.TestLoader() 872 suite = loader.loadTestsFromNames(['testsuite'], m) 873 self.assertIsInstance(suite, loader.suiteClass) 874 875 self.assertEqual(list(suite), [m.testsuite]) 876 877 # "The specifier name is a ``dotted name'' that may resolve ... to ... a 878 # test method within a test case class" 879 def test_loadTestsFromNames__relative_testmethod(self): 880 m = types.ModuleType('m') 881 class MyTestCase(unittest.TestCase): 882 def test(self): 883 pass 884 m.testcase_1 = MyTestCase 885 886 loader = unittest.TestLoader() 887 suite = loader.loadTestsFromNames(['testcase_1.test'], m) 888 self.assertIsInstance(suite, loader.suiteClass) 889 890 ref_suite = unittest.TestSuite([MyTestCase('test')]) 891 self.assertEqual(list(suite), [ref_suite]) 892 893 # #14971: Make sure the dotted name resolution works even if the actual 894 # function doesn't have the same name as is used to find it. 895 def test_loadTestsFromName__function_with_different_name_than_method(self): 896 # lambdas have the name '<lambda>'. 897 m = types.ModuleType('m') 898 class MyTestCase(unittest.TestCase): 899 test = lambda: 1 900 m.testcase_1 = MyTestCase 901 902 loader = unittest.TestLoader() 903 suite = loader.loadTestsFromNames(['testcase_1.test'], m) 904 self.assertIsInstance(suite, loader.suiteClass) 905 906 ref_suite = unittest.TestSuite([MyTestCase('test')]) 907 self.assertEqual(list(suite), [ref_suite]) 908 909 # "The specifier name is a ``dotted name'' that may resolve ... to ... a 910 # test method within a test case class" 911 # 912 # Does the method gracefully handle names that initially look like they 913 # resolve to "a test method within a test case class" but don't? 914 def test_loadTestsFromNames__relative_invalid_testmethod(self): 915 m = types.ModuleType('m') 916 class MyTestCase(unittest.TestCase): 917 def test(self): 918 pass 919 m.testcase_1 = MyTestCase 920 921 loader = unittest.TestLoader() 922 suite = loader.loadTestsFromNames(['testcase_1.testfoo'], m) 923 error, test = self.check_deferred_error(loader, list(suite)[0]) 924 expected = "type object 'MyTestCase' has no attribute 'testfoo'" 925 self.assertIn( 926 expected, error, 927 'missing error string in %r' % error) 928 self.assertRaisesRegex(AttributeError, expected, test.testfoo) 929 930 # "The specifier name is a ``dotted name'' that may resolve ... to 931 # ... a callable object which returns a ... TestSuite instance" 932 def test_loadTestsFromNames__callable__TestSuite(self): 933 m = types.ModuleType('m') 934 testcase_1 = unittest.FunctionTestCase(lambda: None) 935 testcase_2 = unittest.FunctionTestCase(lambda: None) 936 def return_TestSuite(): 937 return unittest.TestSuite([testcase_1, testcase_2]) 938 m.return_TestSuite = return_TestSuite 939 940 loader = unittest.TestLoader() 941 suite = loader.loadTestsFromNames(['return_TestSuite'], m) 942 self.assertIsInstance(suite, loader.suiteClass) 943 944 expected = unittest.TestSuite([testcase_1, testcase_2]) 945 self.assertEqual(list(suite), [expected]) 946 947 # "The specifier name is a ``dotted name'' that may resolve ... to 948 # ... a callable object which returns a TestCase ... instance" 949 def test_loadTestsFromNames__callable__TestCase_instance(self): 950 m = types.ModuleType('m') 951 testcase_1 = unittest.FunctionTestCase(lambda: None) 952 def return_TestCase(): 953 return testcase_1 954 m.return_TestCase = return_TestCase 955 956 loader = unittest.TestLoader() 957 suite = loader.loadTestsFromNames(['return_TestCase'], m) 958 self.assertIsInstance(suite, loader.suiteClass) 959 960 ref_suite = unittest.TestSuite([testcase_1]) 961 self.assertEqual(list(suite), [ref_suite]) 962 963 # "The specifier name is a ``dotted name'' that may resolve ... to 964 # ... a callable object which returns a TestCase or TestSuite instance" 965 # 966 # Are staticmethods handled correctly? 967 def test_loadTestsFromNames__callable__call_staticmethod(self): 968 m = types.ModuleType('m') 969 class Test1(unittest.TestCase): 970 def test(self): 971 pass 972 973 testcase_1 = Test1('test') 974 class Foo(unittest.TestCase): 975 @staticmethod 976 def foo(): 977 return testcase_1 978 m.Foo = Foo 979 980 loader = unittest.TestLoader() 981 suite = loader.loadTestsFromNames(['Foo.foo'], m) 982 self.assertIsInstance(suite, loader.suiteClass) 983 984 ref_suite = unittest.TestSuite([testcase_1]) 985 self.assertEqual(list(suite), [ref_suite]) 986 987 # "The specifier name is a ``dotted name'' that may resolve ... to 988 # ... a callable object which returns a TestCase or TestSuite instance" 989 # 990 # What happens when the callable returns something else? 991 def test_loadTestsFromNames__callable__wrong_type(self): 992 m = types.ModuleType('m') 993 def return_wrong(): 994 return 6 995 m.return_wrong = return_wrong 996 997 loader = unittest.TestLoader() 998 try: 999 suite = loader.loadTestsFromNames(['return_wrong'], m) 1000 except TypeError: 1001 pass 1002 else: 1003 self.fail("TestLoader.loadTestsFromNames failed to raise TypeError") 1004 1005 # "The specifier can refer to modules and packages which have not been 1006 # imported; they will be imported as a side-effect" 1007 def test_loadTestsFromNames__module_not_loaded(self): 1008 # We're going to try to load this module as a side-effect, so it 1009 # better not be loaded before we try. 1010 # 1011 module_name = 'unittest.test.dummy' 1012 sys.modules.pop(module_name, None) 1013 1014 loader = unittest.TestLoader() 1015 try: 1016 suite = loader.loadTestsFromNames([module_name]) 1017 1018 self.assertIsInstance(suite, loader.suiteClass) 1019 self.assertEqual(list(suite), [unittest.TestSuite()]) 1020 1021 # module should now be loaded, thanks to loadTestsFromName() 1022 self.assertIn(module_name, sys.modules) 1023 finally: 1024 if module_name in sys.modules: 1025 del sys.modules[module_name] 1026 1027 ################################################################ 1028 ### /Tests for TestLoader.loadTestsFromNames() 1029 1030 ### Tests for TestLoader.getTestCaseNames() 1031 ################################################################ 1032 1033 # "Return a sorted sequence of method names found within testCaseClass" 1034 # 1035 # Test.foobar is defined to make sure getTestCaseNames() respects 1036 # loader.testMethodPrefix 1037 def test_getTestCaseNames(self): 1038 class Test(unittest.TestCase): 1039 def test_1(self): pass 1040 def test_2(self): pass 1041 def foobar(self): pass 1042 1043 loader = unittest.TestLoader() 1044 1045 self.assertEqual(loader.getTestCaseNames(Test), ['test_1', 'test_2']) 1046 1047 # "Return a sorted sequence of method names found within testCaseClass" 1048 # 1049 # Does getTestCaseNames() behave appropriately if no tests are found? 1050 def test_getTestCaseNames__no_tests(self): 1051 class Test(unittest.TestCase): 1052 def foobar(self): pass 1053 1054 loader = unittest.TestLoader() 1055 1056 self.assertEqual(loader.getTestCaseNames(Test), []) 1057 1058 # "Return a sorted sequence of method names found within testCaseClass" 1059 # 1060 # Are not-TestCases handled gracefully? 1061 # 1062 # XXX This should raise a TypeError, not return a list 1063 # 1064 # XXX It's too late in the 2.5 release cycle to fix this, but it should 1065 # probably be revisited for 2.6 1066 def test_getTestCaseNames__not_a_TestCase(self): 1067 class BadCase(int): 1068 def test_foo(self): 1069 pass 1070 1071 loader = unittest.TestLoader() 1072 names = loader.getTestCaseNames(BadCase) 1073 1074 self.assertEqual(names, ['test_foo']) 1075 1076 # "Return a sorted sequence of method names found within testCaseClass" 1077 # 1078 # Make sure inherited names are handled. 1079 # 1080 # TestP.foobar is defined to make sure getTestCaseNames() respects 1081 # loader.testMethodPrefix 1082 def test_getTestCaseNames__inheritance(self): 1083 class TestP(unittest.TestCase): 1084 def test_1(self): pass 1085 def test_2(self): pass 1086 def foobar(self): pass 1087 1088 class TestC(TestP): 1089 def test_1(self): pass 1090 def test_3(self): pass 1091 1092 loader = unittest.TestLoader() 1093 1094 names = ['test_1', 'test_2', 'test_3'] 1095 self.assertEqual(loader.getTestCaseNames(TestC), names) 1096 1097 # "Return a sorted sequence of method names found within testCaseClass" 1098 # 1099 # If TestLoader.testNamePatterns is set, only tests that match one of these 1100 # patterns should be included. 1101 def test_getTestCaseNames__testNamePatterns(self): 1102 class MyTest(unittest.TestCase): 1103 def test_1(self): pass 1104 def test_2(self): pass 1105 def foobar(self): pass 1106 1107 loader = unittest.TestLoader() 1108 1109 loader.testNamePatterns = [] 1110 self.assertEqual(loader.getTestCaseNames(MyTest), []) 1111 1112 loader.testNamePatterns = ['*1'] 1113 self.assertEqual(loader.getTestCaseNames(MyTest), ['test_1']) 1114 1115 loader.testNamePatterns = ['*1', '*2'] 1116 self.assertEqual(loader.getTestCaseNames(MyTest), ['test_1', 'test_2']) 1117 1118 loader.testNamePatterns = ['*My*'] 1119 self.assertEqual(loader.getTestCaseNames(MyTest), ['test_1', 'test_2']) 1120 1121 loader.testNamePatterns = ['*my*'] 1122 self.assertEqual(loader.getTestCaseNames(MyTest), []) 1123 1124 # "Return a sorted sequence of method names found within testCaseClass" 1125 # 1126 # If TestLoader.testNamePatterns is set, only tests that match one of these 1127 # patterns should be included. 1128 # 1129 # For backwards compatibility reasons (see bpo-32071), the check may only 1130 # touch a TestCase's attribute if it starts with the test method prefix. 1131 def test_getTestCaseNames__testNamePatterns__attribute_access_regression(self): 1132 class Trap: 1133 def __get__(*ignored): 1134 self.fail('Non-test attribute accessed') 1135 1136 class MyTest(unittest.TestCase): 1137 def test_1(self): pass 1138 foobar = Trap() 1139 1140 loader = unittest.TestLoader() 1141 self.assertEqual(loader.getTestCaseNames(MyTest), ['test_1']) 1142 1143 loader = unittest.TestLoader() 1144 loader.testNamePatterns = [] 1145 self.assertEqual(loader.getTestCaseNames(MyTest), []) 1146 1147 ################################################################ 1148 ### /Tests for TestLoader.getTestCaseNames() 1149 1150 ### Tests for TestLoader.testMethodPrefix 1151 ################################################################ 1152 1153 # "String giving the prefix of method names which will be interpreted as 1154 # test methods" 1155 # 1156 # Implicit in the documentation is that testMethodPrefix is respected by 1157 # all loadTestsFrom* methods. 1158 def test_testMethodPrefix__loadTestsFromTestCase(self): 1159 class Foo(unittest.TestCase): 1160 def test_1(self): pass 1161 def test_2(self): pass 1162 def foo_bar(self): pass 1163 1164 tests_1 = unittest.TestSuite([Foo('foo_bar')]) 1165 tests_2 = unittest.TestSuite([Foo('test_1'), Foo('test_2')]) 1166 1167 loader = unittest.TestLoader() 1168 loader.testMethodPrefix = 'foo' 1169 self.assertEqual(loader.loadTestsFromTestCase(Foo), tests_1) 1170 1171 loader.testMethodPrefix = 'test' 1172 self.assertEqual(loader.loadTestsFromTestCase(Foo), tests_2) 1173 1174 # "String giving the prefix of method names which will be interpreted as 1175 # test methods" 1176 # 1177 # Implicit in the documentation is that testMethodPrefix is respected by 1178 # all loadTestsFrom* methods. 1179 def test_testMethodPrefix__loadTestsFromModule(self): 1180 m = types.ModuleType('m') 1181 class Foo(unittest.TestCase): 1182 def test_1(self): pass 1183 def test_2(self): pass 1184 def foo_bar(self): pass 1185 m.Foo = Foo 1186 1187 tests_1 = [unittest.TestSuite([Foo('foo_bar')])] 1188 tests_2 = [unittest.TestSuite([Foo('test_1'), Foo('test_2')])] 1189 1190 loader = unittest.TestLoader() 1191 loader.testMethodPrefix = 'foo' 1192 self.assertEqual(list(loader.loadTestsFromModule(m)), tests_1) 1193 1194 loader.testMethodPrefix = 'test' 1195 self.assertEqual(list(loader.loadTestsFromModule(m)), tests_2) 1196 1197 # "String giving the prefix of method names which will be interpreted as 1198 # test methods" 1199 # 1200 # Implicit in the documentation is that testMethodPrefix is respected by 1201 # all loadTestsFrom* methods. 1202 def test_testMethodPrefix__loadTestsFromName(self): 1203 m = types.ModuleType('m') 1204 class Foo(unittest.TestCase): 1205 def test_1(self): pass 1206 def test_2(self): pass 1207 def foo_bar(self): pass 1208 m.Foo = Foo 1209 1210 tests_1 = unittest.TestSuite([Foo('foo_bar')]) 1211 tests_2 = unittest.TestSuite([Foo('test_1'), Foo('test_2')]) 1212 1213 loader = unittest.TestLoader() 1214 loader.testMethodPrefix = 'foo' 1215 self.assertEqual(loader.loadTestsFromName('Foo', m), tests_1) 1216 1217 loader.testMethodPrefix = 'test' 1218 self.assertEqual(loader.loadTestsFromName('Foo', m), tests_2) 1219 1220 # "String giving the prefix of method names which will be interpreted as 1221 # test methods" 1222 # 1223 # Implicit in the documentation is that testMethodPrefix is respected by 1224 # all loadTestsFrom* methods. 1225 def test_testMethodPrefix__loadTestsFromNames(self): 1226 m = types.ModuleType('m') 1227 class Foo(unittest.TestCase): 1228 def test_1(self): pass 1229 def test_2(self): pass 1230 def foo_bar(self): pass 1231 m.Foo = Foo 1232 1233 tests_1 = unittest.TestSuite([unittest.TestSuite([Foo('foo_bar')])]) 1234 tests_2 = unittest.TestSuite([Foo('test_1'), Foo('test_2')]) 1235 tests_2 = unittest.TestSuite([tests_2]) 1236 1237 loader = unittest.TestLoader() 1238 loader.testMethodPrefix = 'foo' 1239 self.assertEqual(loader.loadTestsFromNames(['Foo'], m), tests_1) 1240 1241 loader.testMethodPrefix = 'test' 1242 self.assertEqual(loader.loadTestsFromNames(['Foo'], m), tests_2) 1243 1244 # "The default value is 'test'" 1245 def test_testMethodPrefix__default_value(self): 1246 loader = unittest.TestLoader() 1247 self.assertEqual(loader.testMethodPrefix, 'test') 1248 1249 ################################################################ 1250 ### /Tests for TestLoader.testMethodPrefix 1251 1252 ### Tests for TestLoader.sortTestMethodsUsing 1253 ################################################################ 1254 1255 # "Function to be used to compare method names when sorting them in 1256 # getTestCaseNames() and all the loadTestsFromX() methods" 1257 def test_sortTestMethodsUsing__loadTestsFromTestCase(self): 1258 def reversed_cmp(x, y): 1259 return -((x > y) - (x < y)) 1260 1261 class Foo(unittest.TestCase): 1262 def test_1(self): pass 1263 def test_2(self): pass 1264 1265 loader = unittest.TestLoader() 1266 loader.sortTestMethodsUsing = reversed_cmp 1267 1268 tests = loader.suiteClass([Foo('test_2'), Foo('test_1')]) 1269 self.assertEqual(loader.loadTestsFromTestCase(Foo), tests) 1270 1271 # "Function to be used to compare method names when sorting them in 1272 # getTestCaseNames() and all the loadTestsFromX() methods" 1273 def test_sortTestMethodsUsing__loadTestsFromModule(self): 1274 def reversed_cmp(x, y): 1275 return -((x > y) - (x < y)) 1276 1277 m = types.ModuleType('m') 1278 class Foo(unittest.TestCase): 1279 def test_1(self): pass 1280 def test_2(self): pass 1281 m.Foo = Foo 1282 1283 loader = unittest.TestLoader() 1284 loader.sortTestMethodsUsing = reversed_cmp 1285 1286 tests = [loader.suiteClass([Foo('test_2'), Foo('test_1')])] 1287 self.assertEqual(list(loader.loadTestsFromModule(m)), tests) 1288 1289 # "Function to be used to compare method names when sorting them in 1290 # getTestCaseNames() and all the loadTestsFromX() methods" 1291 def test_sortTestMethodsUsing__loadTestsFromName(self): 1292 def reversed_cmp(x, y): 1293 return -((x > y) - (x < y)) 1294 1295 m = types.ModuleType('m') 1296 class Foo(unittest.TestCase): 1297 def test_1(self): pass 1298 def test_2(self): pass 1299 m.Foo = Foo 1300 1301 loader = unittest.TestLoader() 1302 loader.sortTestMethodsUsing = reversed_cmp 1303 1304 tests = loader.suiteClass([Foo('test_2'), Foo('test_1')]) 1305 self.assertEqual(loader.loadTestsFromName('Foo', m), tests) 1306 1307 # "Function to be used to compare method names when sorting them in 1308 # getTestCaseNames() and all the loadTestsFromX() methods" 1309 def test_sortTestMethodsUsing__loadTestsFromNames(self): 1310 def reversed_cmp(x, y): 1311 return -((x > y) - (x < y)) 1312 1313 m = types.ModuleType('m') 1314 class Foo(unittest.TestCase): 1315 def test_1(self): pass 1316 def test_2(self): pass 1317 m.Foo = Foo 1318 1319 loader = unittest.TestLoader() 1320 loader.sortTestMethodsUsing = reversed_cmp 1321 1322 tests = [loader.suiteClass([Foo('test_2'), Foo('test_1')])] 1323 self.assertEqual(list(loader.loadTestsFromNames(['Foo'], m)), tests) 1324 1325 # "Function to be used to compare method names when sorting them in 1326 # getTestCaseNames()" 1327 # 1328 # Does it actually affect getTestCaseNames()? 1329 def test_sortTestMethodsUsing__getTestCaseNames(self): 1330 def reversed_cmp(x, y): 1331 return -((x > y) - (x < y)) 1332 1333 class Foo(unittest.TestCase): 1334 def test_1(self): pass 1335 def test_2(self): pass 1336 1337 loader = unittest.TestLoader() 1338 loader.sortTestMethodsUsing = reversed_cmp 1339 1340 test_names = ['test_2', 'test_1'] 1341 self.assertEqual(loader.getTestCaseNames(Foo), test_names) 1342 1343 # "The default value is the built-in cmp() function" 1344 # Since cmp is now defunct, we simply verify that the results 1345 # occur in the same order as they would with the default sort. 1346 def test_sortTestMethodsUsing__default_value(self): 1347 loader = unittest.TestLoader() 1348 1349 class Foo(unittest.TestCase): 1350 def test_2(self): pass 1351 def test_3(self): pass 1352 def test_1(self): pass 1353 1354 test_names = ['test_2', 'test_3', 'test_1'] 1355 self.assertEqual(loader.getTestCaseNames(Foo), sorted(test_names)) 1356 1357 1358 # "it can be set to None to disable the sort." 1359 # 1360 # XXX How is this different from reassigning cmp? Are the tests returned 1361 # in a random order or something? This behaviour should die 1362 def test_sortTestMethodsUsing__None(self): 1363 class Foo(unittest.TestCase): 1364 def test_1(self): pass 1365 def test_2(self): pass 1366 1367 loader = unittest.TestLoader() 1368 loader.sortTestMethodsUsing = None 1369 1370 test_names = ['test_2', 'test_1'] 1371 self.assertEqual(set(loader.getTestCaseNames(Foo)), set(test_names)) 1372 1373 ################################################################ 1374 ### /Tests for TestLoader.sortTestMethodsUsing 1375 1376 ### Tests for TestLoader.suiteClass 1377 ################################################################ 1378 1379 # "Callable object that constructs a test suite from a list of tests." 1380 def test_suiteClass__loadTestsFromTestCase(self): 1381 class Foo(unittest.TestCase): 1382 def test_1(self): pass 1383 def test_2(self): pass 1384 def foo_bar(self): pass 1385 1386 tests = [Foo('test_1'), Foo('test_2')] 1387 1388 loader = unittest.TestLoader() 1389 loader.suiteClass = list 1390 self.assertEqual(loader.loadTestsFromTestCase(Foo), tests) 1391 1392 # It is implicit in the documentation for TestLoader.suiteClass that 1393 # all TestLoader.loadTestsFrom* methods respect it. Let's make sure 1394 def test_suiteClass__loadTestsFromModule(self): 1395 m = types.ModuleType('m') 1396 class Foo(unittest.TestCase): 1397 def test_1(self): pass 1398 def test_2(self): pass 1399 def foo_bar(self): pass 1400 m.Foo = Foo 1401 1402 tests = [[Foo('test_1'), Foo('test_2')]] 1403 1404 loader = unittest.TestLoader() 1405 loader.suiteClass = list 1406 self.assertEqual(loader.loadTestsFromModule(m), tests) 1407 1408 # It is implicit in the documentation for TestLoader.suiteClass that 1409 # all TestLoader.loadTestsFrom* methods respect it. Let's make sure 1410 def test_suiteClass__loadTestsFromName(self): 1411 m = types.ModuleType('m') 1412 class Foo(unittest.TestCase): 1413 def test_1(self): pass 1414 def test_2(self): pass 1415 def foo_bar(self): pass 1416 m.Foo = Foo 1417 1418 tests = [Foo('test_1'), Foo('test_2')] 1419 1420 loader = unittest.TestLoader() 1421 loader.suiteClass = list 1422 self.assertEqual(loader.loadTestsFromName('Foo', m), tests) 1423 1424 # It is implicit in the documentation for TestLoader.suiteClass that 1425 # all TestLoader.loadTestsFrom* methods respect it. Let's make sure 1426 def test_suiteClass__loadTestsFromNames(self): 1427 m = types.ModuleType('m') 1428 class Foo(unittest.TestCase): 1429 def test_1(self): pass 1430 def test_2(self): pass 1431 def foo_bar(self): pass 1432 m.Foo = Foo 1433 1434 tests = [[Foo('test_1'), Foo('test_2')]] 1435 1436 loader = unittest.TestLoader() 1437 loader.suiteClass = list 1438 self.assertEqual(loader.loadTestsFromNames(['Foo'], m), tests) 1439 1440 # "The default value is the TestSuite class" 1441 def test_suiteClass__default_value(self): 1442 loader = unittest.TestLoader() 1443 self.assertIs(loader.suiteClass, unittest.TestSuite) 1444 1445 1446 def test_partial_functions(self): 1447 def noop(arg): 1448 pass 1449 1450 class Foo(unittest.TestCase): 1451 pass 1452 1453 setattr(Foo, 'test_partial', functools.partial(noop, None)) 1454 1455 loader = unittest.TestLoader() 1456 1457 test_names = ['test_partial'] 1458 self.assertEqual(loader.getTestCaseNames(Foo), test_names) 1459 1460 1461class TestObsoleteFunctions(unittest.TestCase): 1462 class MyTestSuite(unittest.TestSuite): 1463 pass 1464 1465 class MyTestCase(unittest.TestCase): 1466 def check_1(self): pass 1467 def check_2(self): pass 1468 def test(self): pass 1469 1470 @staticmethod 1471 def reverse_three_way_cmp(a, b): 1472 return unittest.util.three_way_cmp(b, a) 1473 1474 def test_getTestCaseNames(self): 1475 with self.assertWarns(DeprecationWarning) as w: 1476 tests = unittest.getTestCaseNames(self.MyTestCase, 1477 prefix='check', sortUsing=self.reverse_three_way_cmp, 1478 testNamePatterns=None) 1479 self.assertEqual(w.warnings[0].filename, __file__) 1480 self.assertEqual(tests, ['check_2', 'check_1']) 1481 1482 def test_makeSuite(self): 1483 with self.assertWarns(DeprecationWarning) as w: 1484 suite = unittest.makeSuite(self.MyTestCase, 1485 prefix='check', sortUsing=self.reverse_three_way_cmp, 1486 suiteClass=self.MyTestSuite) 1487 self.assertEqual(w.warnings[0].filename, __file__) 1488 self.assertIsInstance(suite, self.MyTestSuite) 1489 expected = self.MyTestSuite([self.MyTestCase('check_2'), 1490 self.MyTestCase('check_1')]) 1491 self.assertEqual(suite, expected) 1492 1493 def test_findTestCases(self): 1494 m = types.ModuleType('m') 1495 m.testcase_1 = self.MyTestCase 1496 1497 with self.assertWarns(DeprecationWarning) as w: 1498 suite = unittest.findTestCases(m, 1499 prefix='check', sortUsing=self.reverse_three_way_cmp, 1500 suiteClass=self.MyTestSuite) 1501 self.assertEqual(w.warnings[0].filename, __file__) 1502 self.assertIsInstance(suite, self.MyTestSuite) 1503 expected = [self.MyTestSuite([self.MyTestCase('check_2'), 1504 self.MyTestCase('check_1')])] 1505 self.assertEqual(list(suite), expected) 1506 1507 1508if __name__ == "__main__": 1509 unittest.main() 1510