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