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