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