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