xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/unittest/test/test_result.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1import io
2import sys
3import textwrap
4
5from test.support import warnings_helper, captured_stdout, captured_stderr
6
7import traceback
8import unittest
9from unittest.util import strclass
10
11
12class MockTraceback(object):
13    class TracebackException:
14        def __init__(self, *args, **kwargs):
15            self.capture_locals = kwargs.get('capture_locals', False)
16        def format(self):
17            result = ['A traceback']
18            if self.capture_locals:
19                result.append('locals')
20            return result
21
22def restore_traceback():
23    unittest.result.traceback = traceback
24
25
26def bad_cleanup1():
27    print('do cleanup1')
28    raise TypeError('bad cleanup1')
29
30
31def bad_cleanup2():
32    print('do cleanup2')
33    raise ValueError('bad cleanup2')
34
35
36class BufferedWriter:
37    def __init__(self):
38        self.result = ''
39        self.buffer = ''
40
41    def write(self, arg):
42        self.buffer += arg
43
44    def flush(self):
45        self.result += self.buffer
46        self.buffer = ''
47
48    def getvalue(self):
49        return self.result
50
51
52class Test_TestResult(unittest.TestCase):
53    # Note: there are not separate tests for TestResult.wasSuccessful(),
54    # TestResult.errors, TestResult.failures, TestResult.testsRun or
55    # TestResult.shouldStop because these only have meaning in terms of
56    # other TestResult methods.
57    #
58    # Accordingly, tests for the aforenamed attributes are incorporated
59    # in with the tests for the defining methods.
60    ################################################################
61
62    def test_init(self):
63        result = unittest.TestResult()
64
65        self.assertTrue(result.wasSuccessful())
66        self.assertEqual(len(result.errors), 0)
67        self.assertEqual(len(result.failures), 0)
68        self.assertEqual(result.testsRun, 0)
69        self.assertEqual(result.shouldStop, False)
70        self.assertIsNone(result._stdout_buffer)
71        self.assertIsNone(result._stderr_buffer)
72
73    # "This method can be called to signal that the set of tests being
74    # run should be aborted by setting the TestResult's shouldStop
75    # attribute to True."
76    def test_stop(self):
77        result = unittest.TestResult()
78
79        result.stop()
80
81        self.assertEqual(result.shouldStop, True)
82
83    # "Called when the test case test is about to be run. The default
84    # implementation simply increments the instance's testsRun counter."
85    def test_startTest(self):
86        class Foo(unittest.TestCase):
87            def test_1(self):
88                pass
89
90        test = Foo('test_1')
91
92        result = unittest.TestResult()
93
94        result.startTest(test)
95
96        self.assertTrue(result.wasSuccessful())
97        self.assertEqual(len(result.errors), 0)
98        self.assertEqual(len(result.failures), 0)
99        self.assertEqual(result.testsRun, 1)
100        self.assertEqual(result.shouldStop, False)
101
102        result.stopTest(test)
103
104    # "Called after the test case test has been executed, regardless of
105    # the outcome. The default implementation does nothing."
106    def test_stopTest(self):
107        class Foo(unittest.TestCase):
108            def test_1(self):
109                pass
110
111        test = Foo('test_1')
112
113        result = unittest.TestResult()
114
115        result.startTest(test)
116
117        self.assertTrue(result.wasSuccessful())
118        self.assertEqual(len(result.errors), 0)
119        self.assertEqual(len(result.failures), 0)
120        self.assertEqual(result.testsRun, 1)
121        self.assertEqual(result.shouldStop, False)
122
123        result.stopTest(test)
124
125        # Same tests as above; make sure nothing has changed
126        self.assertTrue(result.wasSuccessful())
127        self.assertEqual(len(result.errors), 0)
128        self.assertEqual(len(result.failures), 0)
129        self.assertEqual(result.testsRun, 1)
130        self.assertEqual(result.shouldStop, False)
131
132    # "Called before and after tests are run. The default implementation does nothing."
133    def test_startTestRun_stopTestRun(self):
134        result = unittest.TestResult()
135        result.startTestRun()
136        result.stopTestRun()
137
138    # "addSuccess(test)"
139    # ...
140    # "Called when the test case test succeeds"
141    # ...
142    # "wasSuccessful() - Returns True if all tests run so far have passed,
143    # otherwise returns False"
144    # ...
145    # "testsRun - The total number of tests run so far."
146    # ...
147    # "errors - A list containing 2-tuples of TestCase instances and
148    # formatted tracebacks. Each tuple represents a test which raised an
149    # unexpected exception. Contains formatted
150    # tracebacks instead of sys.exc_info() results."
151    # ...
152    # "failures - A list containing 2-tuples of TestCase instances and
153    # formatted tracebacks. Each tuple represents a test where a failure was
154    # explicitly signalled using the TestCase.fail*() or TestCase.assert*()
155    # methods. Contains formatted tracebacks instead
156    # of sys.exc_info() results."
157    def test_addSuccess(self):
158        class Foo(unittest.TestCase):
159            def test_1(self):
160                pass
161
162        test = Foo('test_1')
163
164        result = unittest.TestResult()
165
166        result.startTest(test)
167        result.addSuccess(test)
168        result.stopTest(test)
169
170        self.assertTrue(result.wasSuccessful())
171        self.assertEqual(len(result.errors), 0)
172        self.assertEqual(len(result.failures), 0)
173        self.assertEqual(result.testsRun, 1)
174        self.assertEqual(result.shouldStop, False)
175
176    # "addFailure(test, err)"
177    # ...
178    # "Called when the test case test signals a failure. err is a tuple of
179    # the form returned by sys.exc_info(): (type, value, traceback)"
180    # ...
181    # "wasSuccessful() - Returns True if all tests run so far have passed,
182    # otherwise returns False"
183    # ...
184    # "testsRun - The total number of tests run so far."
185    # ...
186    # "errors - A list containing 2-tuples of TestCase instances and
187    # formatted tracebacks. Each tuple represents a test which raised an
188    # unexpected exception. Contains formatted
189    # tracebacks instead of sys.exc_info() results."
190    # ...
191    # "failures - A list containing 2-tuples of TestCase instances and
192    # formatted tracebacks. Each tuple represents a test where a failure was
193    # explicitly signalled using the TestCase.fail*() or TestCase.assert*()
194    # methods. Contains formatted tracebacks instead
195    # of sys.exc_info() results."
196    def test_addFailure(self):
197        class Foo(unittest.TestCase):
198            def test_1(self):
199                pass
200
201        test = Foo('test_1')
202        try:
203            test.fail("foo")
204        except:
205            exc_info_tuple = sys.exc_info()
206
207        result = unittest.TestResult()
208
209        result.startTest(test)
210        result.addFailure(test, exc_info_tuple)
211        result.stopTest(test)
212
213        self.assertFalse(result.wasSuccessful())
214        self.assertEqual(len(result.errors), 0)
215        self.assertEqual(len(result.failures), 1)
216        self.assertEqual(result.testsRun, 1)
217        self.assertEqual(result.shouldStop, False)
218
219        test_case, formatted_exc = result.failures[0]
220        self.assertIs(test_case, test)
221        self.assertIsInstance(formatted_exc, str)
222
223    def test_addFailure_filter_traceback_frames(self):
224        class Foo(unittest.TestCase):
225            def test_1(self):
226                pass
227
228        test = Foo('test_1')
229        def get_exc_info():
230            try:
231                test.fail("foo")
232            except:
233                return sys.exc_info()
234
235        exc_info_tuple = get_exc_info()
236
237        full_exc = traceback.format_exception(*exc_info_tuple)
238
239        result = unittest.TestResult()
240        result.startTest(test)
241        result.addFailure(test, exc_info_tuple)
242        result.stopTest(test)
243
244        formatted_exc = result.failures[0][1]
245        dropped = [l for l in full_exc if l not in formatted_exc]
246        self.assertEqual(len(dropped), 1)
247        self.assertIn("raise self.failureException(msg)", dropped[0])
248
249    def test_addFailure_filter_traceback_frames_context(self):
250        class Foo(unittest.TestCase):
251            def test_1(self):
252                pass
253
254        test = Foo('test_1')
255        def get_exc_info():
256            try:
257                try:
258                    test.fail("foo")
259                except:
260                    raise ValueError(42)
261            except:
262                return sys.exc_info()
263
264        exc_info_tuple = get_exc_info()
265
266        full_exc = traceback.format_exception(*exc_info_tuple)
267
268        result = unittest.TestResult()
269        result.startTest(test)
270        result.addFailure(test, exc_info_tuple)
271        result.stopTest(test)
272
273        formatted_exc = result.failures[0][1]
274        dropped = [l for l in full_exc if l not in formatted_exc]
275        self.assertEqual(len(dropped), 1)
276        self.assertIn("raise self.failureException(msg)", dropped[0])
277
278    def test_addFailure_filter_traceback_frames_chained_exception_self_loop(self):
279        class Foo(unittest.TestCase):
280            def test_1(self):
281                pass
282
283        def get_exc_info():
284            try:
285                loop = Exception("Loop")
286                loop.__cause__ = loop
287                loop.__context__ = loop
288                raise loop
289            except:
290                return sys.exc_info()
291
292        exc_info_tuple = get_exc_info()
293
294        test = Foo('test_1')
295        result = unittest.TestResult()
296        result.startTest(test)
297        result.addFailure(test, exc_info_tuple)
298        result.stopTest(test)
299
300        formatted_exc = result.failures[0][1]
301        self.assertEqual(formatted_exc.count("Exception: Loop\n"), 1)
302
303    def test_addFailure_filter_traceback_frames_chained_exception_cycle(self):
304        class Foo(unittest.TestCase):
305            def test_1(self):
306                pass
307
308        def get_exc_info():
309            try:
310                # Create two directionally opposed cycles
311                # __cause__ in one direction, __context__ in the other
312                A, B, C = Exception("A"), Exception("B"), Exception("C")
313                edges = [(C, B), (B, A), (A, C)]
314                for ex1, ex2 in edges:
315                    ex1.__cause__ = ex2
316                    ex2.__context__ = ex1
317                raise C
318            except:
319                return sys.exc_info()
320
321        exc_info_tuple = get_exc_info()
322
323        test = Foo('test_1')
324        result = unittest.TestResult()
325        result.startTest(test)
326        result.addFailure(test, exc_info_tuple)
327        result.stopTest(test)
328
329        formatted_exc = result.failures[0][1]
330        self.assertEqual(formatted_exc.count("Exception: A\n"), 1)
331        self.assertEqual(formatted_exc.count("Exception: B\n"), 1)
332        self.assertEqual(formatted_exc.count("Exception: C\n"), 1)
333
334    # "addError(test, err)"
335    # ...
336    # "Called when the test case test raises an unexpected exception err
337    # is a tuple of the form returned by sys.exc_info():
338    # (type, value, traceback)"
339    # ...
340    # "wasSuccessful() - Returns True if all tests run so far have passed,
341    # otherwise returns False"
342    # ...
343    # "testsRun - The total number of tests run so far."
344    # ...
345    # "errors - A list containing 2-tuples of TestCase instances and
346    # formatted tracebacks. Each tuple represents a test which raised an
347    # unexpected exception. Contains formatted
348    # tracebacks instead of sys.exc_info() results."
349    # ...
350    # "failures - A list containing 2-tuples of TestCase instances and
351    # formatted tracebacks. Each tuple represents a test where a failure was
352    # explicitly signalled using the TestCase.fail*() or TestCase.assert*()
353    # methods. Contains formatted tracebacks instead
354    # of sys.exc_info() results."
355    def test_addError(self):
356        class Foo(unittest.TestCase):
357            def test_1(self):
358                pass
359
360        test = Foo('test_1')
361        try:
362            raise TypeError()
363        except:
364            exc_info_tuple = sys.exc_info()
365
366        result = unittest.TestResult()
367
368        result.startTest(test)
369        result.addError(test, exc_info_tuple)
370        result.stopTest(test)
371
372        self.assertFalse(result.wasSuccessful())
373        self.assertEqual(len(result.errors), 1)
374        self.assertEqual(len(result.failures), 0)
375        self.assertEqual(result.testsRun, 1)
376        self.assertEqual(result.shouldStop, False)
377
378        test_case, formatted_exc = result.errors[0]
379        self.assertIs(test_case, test)
380        self.assertIsInstance(formatted_exc, str)
381
382    def test_addError_locals(self):
383        class Foo(unittest.TestCase):
384            def test_1(self):
385                1/0
386
387        test = Foo('test_1')
388        result = unittest.TestResult()
389        result.tb_locals = True
390
391        unittest.result.traceback = MockTraceback
392        self.addCleanup(restore_traceback)
393        result.startTestRun()
394        test.run(result)
395        result.stopTestRun()
396
397        self.assertEqual(len(result.errors), 1)
398        test_case, formatted_exc = result.errors[0]
399        self.assertEqual('A tracebacklocals', formatted_exc)
400
401    def test_addSubTest(self):
402        class Foo(unittest.TestCase):
403            def test_1(self):
404                nonlocal subtest
405                with self.subTest(foo=1):
406                    subtest = self._subtest
407                    try:
408                        1/0
409                    except ZeroDivisionError:
410                        exc_info_tuple = sys.exc_info()
411                    # Register an error by hand (to check the API)
412                    result.addSubTest(test, subtest, exc_info_tuple)
413                    # Now trigger a failure
414                    self.fail("some recognizable failure")
415
416        subtest = None
417        test = Foo('test_1')
418        result = unittest.TestResult()
419
420        test.run(result)
421
422        self.assertFalse(result.wasSuccessful())
423        self.assertEqual(len(result.errors), 1)
424        self.assertEqual(len(result.failures), 1)
425        self.assertEqual(result.testsRun, 1)
426        self.assertEqual(result.shouldStop, False)
427
428        test_case, formatted_exc = result.errors[0]
429        self.assertIs(test_case, subtest)
430        self.assertIn("ZeroDivisionError", formatted_exc)
431        test_case, formatted_exc = result.failures[0]
432        self.assertIs(test_case, subtest)
433        self.assertIn("some recognizable failure", formatted_exc)
434
435    def testStackFrameTrimming(self):
436        class Frame(object):
437            class tb_frame(object):
438                f_globals = {}
439        result = unittest.TestResult()
440        self.assertFalse(result._is_relevant_tb_level(Frame))
441
442        Frame.tb_frame.f_globals['__unittest'] = True
443        self.assertTrue(result._is_relevant_tb_level(Frame))
444
445    def testFailFast(self):
446        result = unittest.TestResult()
447        result._exc_info_to_string = lambda *_: ''
448        result.failfast = True
449        result.addError(None, None)
450        self.assertTrue(result.shouldStop)
451
452        result = unittest.TestResult()
453        result._exc_info_to_string = lambda *_: ''
454        result.failfast = True
455        result.addFailure(None, None)
456        self.assertTrue(result.shouldStop)
457
458        result = unittest.TestResult()
459        result._exc_info_to_string = lambda *_: ''
460        result.failfast = True
461        result.addUnexpectedSuccess(None)
462        self.assertTrue(result.shouldStop)
463
464    def testFailFastSetByRunner(self):
465        stream = BufferedWriter()
466        runner = unittest.TextTestRunner(stream=stream, failfast=True)
467        def test(result):
468            self.assertTrue(result.failfast)
469        result = runner.run(test)
470        stream.flush()
471        self.assertTrue(stream.getvalue().endswith('\n\nOK\n'))
472
473
474class Test_TextTestResult(unittest.TestCase):
475    maxDiff = None
476
477    def testGetDescriptionWithoutDocstring(self):
478        result = unittest.TextTestResult(None, True, 1)
479        self.assertEqual(
480                result.getDescription(self),
481                'testGetDescriptionWithoutDocstring (' + __name__ +
482                '.Test_TextTestResult.testGetDescriptionWithoutDocstring)')
483
484    def testGetSubTestDescriptionWithoutDocstring(self):
485        with self.subTest(foo=1, bar=2):
486            result = unittest.TextTestResult(None, True, 1)
487            self.assertEqual(
488                    result.getDescription(self._subtest),
489                    'testGetSubTestDescriptionWithoutDocstring (' + __name__ +
490                    '.Test_TextTestResult.testGetSubTestDescriptionWithoutDocstring) (foo=1, bar=2)')
491
492        with self.subTest('some message'):
493            result = unittest.TextTestResult(None, True, 1)
494            self.assertEqual(
495                    result.getDescription(self._subtest),
496                    'testGetSubTestDescriptionWithoutDocstring (' + __name__ +
497                    '.Test_TextTestResult.testGetSubTestDescriptionWithoutDocstring) [some message]')
498
499    def testGetSubTestDescriptionWithoutDocstringAndParams(self):
500        with self.subTest():
501            result = unittest.TextTestResult(None, True, 1)
502            self.assertEqual(
503                    result.getDescription(self._subtest),
504                    'testGetSubTestDescriptionWithoutDocstringAndParams '
505                    '(' + __name__ + '.Test_TextTestResult.testGetSubTestDescriptionWithoutDocstringAndParams) '
506                    '(<subtest>)')
507
508    def testGetSubTestDescriptionForFalsyValues(self):
509        expected = 'testGetSubTestDescriptionForFalsyValues (%s.Test_TextTestResult.testGetSubTestDescriptionForFalsyValues) [%s]'
510        result = unittest.TextTestResult(None, True, 1)
511        for arg in [0, None, []]:
512            with self.subTest(arg):
513                self.assertEqual(
514                    result.getDescription(self._subtest),
515                    expected % (__name__, arg)
516                )
517
518    def testGetNestedSubTestDescriptionWithoutDocstring(self):
519        with self.subTest(foo=1):
520            with self.subTest(baz=2, bar=3):
521                result = unittest.TextTestResult(None, True, 1)
522                self.assertEqual(
523                        result.getDescription(self._subtest),
524                        'testGetNestedSubTestDescriptionWithoutDocstring '
525                        '(' + __name__ + '.Test_TextTestResult.testGetNestedSubTestDescriptionWithoutDocstring) '
526                        '(baz=2, bar=3, foo=1)')
527
528    def testGetDuplicatedNestedSubTestDescriptionWithoutDocstring(self):
529        with self.subTest(foo=1, bar=2):
530            with self.subTest(baz=3, bar=4):
531                result = unittest.TextTestResult(None, True, 1)
532                self.assertEqual(
533                        result.getDescription(self._subtest),
534                        'testGetDuplicatedNestedSubTestDescriptionWithoutDocstring '
535                        '(' + __name__ + '.Test_TextTestResult.testGetDuplicatedNestedSubTestDescriptionWithoutDocstring) (baz=3, bar=4, foo=1)')
536
537    @unittest.skipIf(sys.flags.optimize >= 2,
538                     "Docstrings are omitted with -O2 and above")
539    def testGetDescriptionWithOneLineDocstring(self):
540        """Tests getDescription() for a method with a docstring."""
541        result = unittest.TextTestResult(None, True, 1)
542        self.assertEqual(
543                result.getDescription(self),
544               ('testGetDescriptionWithOneLineDocstring '
545                '(' + __name__ + '.Test_TextTestResult.testGetDescriptionWithOneLineDocstring)\n'
546                'Tests getDescription() for a method with a docstring.'))
547
548    @unittest.skipIf(sys.flags.optimize >= 2,
549                     "Docstrings are omitted with -O2 and above")
550    def testGetSubTestDescriptionWithOneLineDocstring(self):
551        """Tests getDescription() for a method with a docstring."""
552        result = unittest.TextTestResult(None, True, 1)
553        with self.subTest(foo=1, bar=2):
554            self.assertEqual(
555                result.getDescription(self._subtest),
556               ('testGetSubTestDescriptionWithOneLineDocstring '
557                '(' + __name__ + '.Test_TextTestResult.testGetSubTestDescriptionWithOneLineDocstring) '
558                '(foo=1, bar=2)\n'
559
560                'Tests getDescription() for a method with a docstring.'))
561
562    @unittest.skipIf(sys.flags.optimize >= 2,
563                     "Docstrings are omitted with -O2 and above")
564    def testGetDescriptionWithMultiLineDocstring(self):
565        """Tests getDescription() for a method with a longer docstring.
566        The second line of the docstring.
567        """
568        result = unittest.TextTestResult(None, True, 1)
569        self.assertEqual(
570                result.getDescription(self),
571               ('testGetDescriptionWithMultiLineDocstring '
572                '(' + __name__ + '.Test_TextTestResult.testGetDescriptionWithMultiLineDocstring)\n'
573                'Tests getDescription() for a method with a longer '
574                'docstring.'))
575
576    @unittest.skipIf(sys.flags.optimize >= 2,
577                     "Docstrings are omitted with -O2 and above")
578    def testGetSubTestDescriptionWithMultiLineDocstring(self):
579        """Tests getDescription() for a method with a longer docstring.
580        The second line of the docstring.
581        """
582        result = unittest.TextTestResult(None, True, 1)
583        with self.subTest(foo=1, bar=2):
584            self.assertEqual(
585                result.getDescription(self._subtest),
586               ('testGetSubTestDescriptionWithMultiLineDocstring '
587                '(' + __name__ + '.Test_TextTestResult.testGetSubTestDescriptionWithMultiLineDocstring) '
588                '(foo=1, bar=2)\n'
589                'Tests getDescription() for a method with a longer '
590                'docstring.'))
591
592    class Test(unittest.TestCase):
593        def testSuccess(self):
594            pass
595        def testSkip(self):
596            self.skipTest('skip')
597        def testFail(self):
598            self.fail('fail')
599        def testError(self):
600            raise Exception('error')
601        @unittest.expectedFailure
602        def testExpectedFailure(self):
603            self.fail('fail')
604        @unittest.expectedFailure
605        def testUnexpectedSuccess(self):
606            pass
607        def testSubTestSuccess(self):
608            with self.subTest('one', a=1):
609                pass
610            with self.subTest('two', b=2):
611                pass
612        def testSubTestMixed(self):
613            with self.subTest('success', a=1):
614                pass
615            with self.subTest('skip', b=2):
616                self.skipTest('skip')
617            with self.subTest('fail', c=3):
618                self.fail('fail')
619            with self.subTest('error', d=4):
620                raise Exception('error')
621
622        tearDownError = None
623        def tearDown(self):
624            if self.tearDownError is not None:
625                raise self.tearDownError
626
627    def _run_test(self, test_name, verbosity, tearDownError=None):
628        stream = BufferedWriter()
629        stream = unittest.runner._WritelnDecorator(stream)
630        result = unittest.TextTestResult(stream, True, verbosity)
631        test = self.Test(test_name)
632        test.tearDownError = tearDownError
633        test.run(result)
634        return stream.getvalue()
635
636    def testDotsOutput(self):
637        self.assertEqual(self._run_test('testSuccess', 1), '.')
638        self.assertEqual(self._run_test('testSkip', 1), 's')
639        self.assertEqual(self._run_test('testFail', 1), 'F')
640        self.assertEqual(self._run_test('testError', 1), 'E')
641        self.assertEqual(self._run_test('testExpectedFailure', 1), 'x')
642        self.assertEqual(self._run_test('testUnexpectedSuccess', 1), 'u')
643
644    def testLongOutput(self):
645        classname = f'{__name__}.{self.Test.__qualname__}'
646        self.assertEqual(self._run_test('testSuccess', 2),
647                         f'testSuccess ({classname}.testSuccess) ... ok\n')
648        self.assertEqual(self._run_test('testSkip', 2),
649                         f"testSkip ({classname}.testSkip) ... skipped 'skip'\n")
650        self.assertEqual(self._run_test('testFail', 2),
651                         f'testFail ({classname}.testFail) ... FAIL\n')
652        self.assertEqual(self._run_test('testError', 2),
653                         f'testError ({classname}.testError) ... ERROR\n')
654        self.assertEqual(self._run_test('testExpectedFailure', 2),
655                         f'testExpectedFailure ({classname}.testExpectedFailure) ... expected failure\n')
656        self.assertEqual(self._run_test('testUnexpectedSuccess', 2),
657                         f'testUnexpectedSuccess ({classname}.testUnexpectedSuccess) ... unexpected success\n')
658
659    def testDotsOutputSubTestSuccess(self):
660        self.assertEqual(self._run_test('testSubTestSuccess', 1), '.')
661
662    def testLongOutputSubTestSuccess(self):
663        classname = f'{__name__}.{self.Test.__qualname__}'
664        self.assertEqual(self._run_test('testSubTestSuccess', 2),
665                         f'testSubTestSuccess ({classname}.testSubTestSuccess) ... ok\n')
666
667    def testDotsOutputSubTestMixed(self):
668        self.assertEqual(self._run_test('testSubTestMixed', 1), 'sFE')
669
670    def testLongOutputSubTestMixed(self):
671        classname = f'{__name__}.{self.Test.__qualname__}'
672        self.assertEqual(self._run_test('testSubTestMixed', 2),
673                f'testSubTestMixed ({classname}.testSubTestMixed) ... \n'
674                f"  testSubTestMixed ({classname}.testSubTestMixed) [skip] (b=2) ... skipped 'skip'\n"
675                f'  testSubTestMixed ({classname}.testSubTestMixed) [fail] (c=3) ... FAIL\n'
676                f'  testSubTestMixed ({classname}.testSubTestMixed) [error] (d=4) ... ERROR\n')
677
678    def testDotsOutputTearDownFail(self):
679        out = self._run_test('testSuccess', 1, AssertionError('fail'))
680        self.assertEqual(out, 'F')
681        out = self._run_test('testError', 1, AssertionError('fail'))
682        self.assertEqual(out, 'EF')
683        out = self._run_test('testFail', 1, Exception('error'))
684        self.assertEqual(out, 'FE')
685        out = self._run_test('testSkip', 1, AssertionError('fail'))
686        self.assertEqual(out, 'sF')
687
688    def testLongOutputTearDownFail(self):
689        classname = f'{__name__}.{self.Test.__qualname__}'
690        out = self._run_test('testSuccess', 2, AssertionError('fail'))
691        self.assertEqual(out,
692                         f'testSuccess ({classname}.testSuccess) ... FAIL\n')
693        out = self._run_test('testError', 2, AssertionError('fail'))
694        self.assertEqual(out,
695                         f'testError ({classname}.testError) ... ERROR\n'
696                         f'testError ({classname}.testError) ... FAIL\n')
697        out = self._run_test('testFail', 2, Exception('error'))
698        self.assertEqual(out,
699                         f'testFail ({classname}.testFail) ... FAIL\n'
700                         f'testFail ({classname}.testFail) ... ERROR\n')
701        out = self._run_test('testSkip', 2, AssertionError('fail'))
702        self.assertEqual(out,
703                         f"testSkip ({classname}.testSkip) ... skipped 'skip'\n"
704                         f'testSkip ({classname}.testSkip) ... FAIL\n')
705
706
707classDict = dict(unittest.TestResult.__dict__)
708for m in ('addSkip', 'addExpectedFailure', 'addUnexpectedSuccess',
709           '__init__'):
710    del classDict[m]
711
712def __init__(self, stream=None, descriptions=None, verbosity=None):
713    self.failures = []
714    self.errors = []
715    self.testsRun = 0
716    self.shouldStop = False
717    self.buffer = False
718    self.tb_locals = False
719
720classDict['__init__'] = __init__
721OldResult = type('OldResult', (object,), classDict)
722
723class Test_OldTestResult(unittest.TestCase):
724
725    def assertOldResultWarning(self, test, failures):
726        with warnings_helper.check_warnings(
727                ("TestResult has no add.+ method,", RuntimeWarning)):
728            result = OldResult()
729            test.run(result)
730            self.assertEqual(len(result.failures), failures)
731
732    def testOldTestResult(self):
733        class Test(unittest.TestCase):
734            def testSkip(self):
735                self.skipTest('foobar')
736            @unittest.expectedFailure
737            def testExpectedFail(self):
738                raise TypeError
739            @unittest.expectedFailure
740            def testUnexpectedSuccess(self):
741                pass
742
743        for test_name, should_pass in (('testSkip', True),
744                                       ('testExpectedFail', True),
745                                       ('testUnexpectedSuccess', False)):
746            test = Test(test_name)
747            self.assertOldResultWarning(test, int(not should_pass))
748
749    def testOldTestTesultSetup(self):
750        class Test(unittest.TestCase):
751            def setUp(self):
752                self.skipTest('no reason')
753            def testFoo(self):
754                pass
755        self.assertOldResultWarning(Test('testFoo'), 0)
756
757    def testOldTestResultClass(self):
758        @unittest.skip('no reason')
759        class Test(unittest.TestCase):
760            def testFoo(self):
761                pass
762        self.assertOldResultWarning(Test('testFoo'), 0)
763
764    def testOldResultWithRunner(self):
765        class Test(unittest.TestCase):
766            def testFoo(self):
767                pass
768        runner = unittest.TextTestRunner(resultclass=OldResult,
769                                          stream=io.StringIO())
770        # This will raise an exception if TextTestRunner can't handle old
771        # test result objects
772        runner.run(Test('testFoo'))
773
774
775class TestOutputBuffering(unittest.TestCase):
776
777    def setUp(self):
778        self._real_out = sys.stdout
779        self._real_err = sys.stderr
780
781    def tearDown(self):
782        sys.stdout = self._real_out
783        sys.stderr = self._real_err
784
785    def testBufferOutputOff(self):
786        real_out = self._real_out
787        real_err = self._real_err
788
789        result = unittest.TestResult()
790        self.assertFalse(result.buffer)
791
792        self.assertIs(real_out, sys.stdout)
793        self.assertIs(real_err, sys.stderr)
794
795        result.startTest(self)
796
797        self.assertIs(real_out, sys.stdout)
798        self.assertIs(real_err, sys.stderr)
799
800    def testBufferOutputStartTestAddSuccess(self):
801        real_out = self._real_out
802        real_err = self._real_err
803
804        result = unittest.TestResult()
805        self.assertFalse(result.buffer)
806
807        result.buffer = True
808
809        self.assertIs(real_out, sys.stdout)
810        self.assertIs(real_err, sys.stderr)
811
812        result.startTest(self)
813
814        self.assertIsNot(real_out, sys.stdout)
815        self.assertIsNot(real_err, sys.stderr)
816        self.assertIsInstance(sys.stdout, io.StringIO)
817        self.assertIsInstance(sys.stderr, io.StringIO)
818        self.assertIsNot(sys.stdout, sys.stderr)
819
820        out_stream = sys.stdout
821        err_stream = sys.stderr
822
823        result._original_stdout = io.StringIO()
824        result._original_stderr = io.StringIO()
825
826        print('foo')
827        print('bar', file=sys.stderr)
828
829        self.assertEqual(out_stream.getvalue(), 'foo\n')
830        self.assertEqual(err_stream.getvalue(), 'bar\n')
831
832        self.assertEqual(result._original_stdout.getvalue(), '')
833        self.assertEqual(result._original_stderr.getvalue(), '')
834
835        result.addSuccess(self)
836        result.stopTest(self)
837
838        self.assertIs(sys.stdout, result._original_stdout)
839        self.assertIs(sys.stderr, result._original_stderr)
840
841        self.assertEqual(result._original_stdout.getvalue(), '')
842        self.assertEqual(result._original_stderr.getvalue(), '')
843
844        self.assertEqual(out_stream.getvalue(), '')
845        self.assertEqual(err_stream.getvalue(), '')
846
847
848    def getStartedResult(self):
849        result = unittest.TestResult()
850        result.buffer = True
851        result.startTest(self)
852        return result
853
854    def testBufferOutputAddErrorOrFailure(self):
855        unittest.result.traceback = MockTraceback
856        self.addCleanup(restore_traceback)
857
858        for message_attr, add_attr, include_error in [
859            ('errors', 'addError', True),
860            ('failures', 'addFailure', False),
861            ('errors', 'addError', True),
862            ('failures', 'addFailure', False)
863        ]:
864            result = self.getStartedResult()
865            buffered_out = sys.stdout
866            buffered_err = sys.stderr
867            result._original_stdout = io.StringIO()
868            result._original_stderr = io.StringIO()
869
870            print('foo', file=sys.stdout)
871            if include_error:
872                print('bar', file=sys.stderr)
873
874
875            addFunction = getattr(result, add_attr)
876            addFunction(self, (None, None, None))
877            result.stopTest(self)
878
879            result_list = getattr(result, message_attr)
880            self.assertEqual(len(result_list), 1)
881
882            test, message = result_list[0]
883            expectedOutMessage = textwrap.dedent("""
884                Stdout:
885                foo
886            """)
887            expectedErrMessage = ''
888            if include_error:
889                expectedErrMessage = textwrap.dedent("""
890                Stderr:
891                bar
892            """)
893
894            expectedFullMessage = 'A traceback%s%s' % (expectedOutMessage, expectedErrMessage)
895
896            self.assertIs(test, self)
897            self.assertEqual(result._original_stdout.getvalue(), expectedOutMessage)
898            self.assertEqual(result._original_stderr.getvalue(), expectedErrMessage)
899            self.assertMultiLineEqual(message, expectedFullMessage)
900
901    def testBufferSetUp(self):
902        with captured_stdout() as stdout:
903            result = unittest.TestResult()
904        result.buffer = True
905
906        class Foo(unittest.TestCase):
907            def setUp(self):
908                print('set up')
909                1/0
910            def test_foo(self):
911                pass
912        suite = unittest.TestSuite([Foo('test_foo')])
913        suite(result)
914        expected_out = '\nStdout:\nset up\n'
915        self.assertEqual(stdout.getvalue(), expected_out)
916        self.assertEqual(len(result.errors), 1)
917        description = f'test_foo ({strclass(Foo)}.test_foo)'
918        test_case, formatted_exc = result.errors[0]
919        self.assertEqual(str(test_case), description)
920        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
921        self.assertIn(expected_out, formatted_exc)
922
923    def testBufferTearDown(self):
924        with captured_stdout() as stdout:
925            result = unittest.TestResult()
926        result.buffer = True
927
928        class Foo(unittest.TestCase):
929            def tearDown(self):
930                print('tear down')
931                1/0
932            def test_foo(self):
933                pass
934        suite = unittest.TestSuite([Foo('test_foo')])
935        suite(result)
936        expected_out = '\nStdout:\ntear down\n'
937        self.assertEqual(stdout.getvalue(), expected_out)
938        self.assertEqual(len(result.errors), 1)
939        description = f'test_foo ({strclass(Foo)}.test_foo)'
940        test_case, formatted_exc = result.errors[0]
941        self.assertEqual(str(test_case), description)
942        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
943        self.assertIn(expected_out, formatted_exc)
944
945    def testBufferDoCleanups(self):
946        with captured_stdout() as stdout:
947            result = unittest.TestResult()
948        result.buffer = True
949
950        class Foo(unittest.TestCase):
951            def setUp(self):
952                print('set up')
953                self.addCleanup(bad_cleanup1)
954                self.addCleanup(bad_cleanup2)
955            def test_foo(self):
956                pass
957        suite = unittest.TestSuite([Foo('test_foo')])
958        suite(result)
959        expected_out = '\nStdout:\nset up\ndo cleanup2\ndo cleanup1\n'
960        self.assertEqual(stdout.getvalue(), expected_out)
961        self.assertEqual(len(result.errors), 2)
962        description = f'test_foo ({strclass(Foo)}.test_foo)'
963        test_case, formatted_exc = result.errors[0]
964        self.assertEqual(str(test_case), description)
965        self.assertIn('ValueError: bad cleanup2', formatted_exc)
966        self.assertNotIn('TypeError', formatted_exc)
967        self.assertIn('\nStdout:\nset up\ndo cleanup2\n', formatted_exc)
968        self.assertNotIn('\ndo cleanup1\n', formatted_exc)
969        test_case, formatted_exc = result.errors[1]
970        self.assertEqual(str(test_case), description)
971        self.assertIn('TypeError: bad cleanup1', formatted_exc)
972        self.assertNotIn('ValueError', formatted_exc)
973        self.assertIn(expected_out, formatted_exc)
974
975    def testBufferSetUp_DoCleanups(self):
976        with captured_stdout() as stdout:
977            result = unittest.TestResult()
978        result.buffer = True
979
980        class Foo(unittest.TestCase):
981            def setUp(self):
982                print('set up')
983                self.addCleanup(bad_cleanup1)
984                self.addCleanup(bad_cleanup2)
985                1/0
986            def test_foo(self):
987                pass
988        suite = unittest.TestSuite([Foo('test_foo')])
989        suite(result)
990        expected_out = '\nStdout:\nset up\ndo cleanup2\ndo cleanup1\n'
991        self.assertEqual(stdout.getvalue(), expected_out)
992        self.assertEqual(len(result.errors), 3)
993        description = f'test_foo ({strclass(Foo)}.test_foo)'
994        test_case, formatted_exc = result.errors[0]
995        self.assertEqual(str(test_case), description)
996        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
997        self.assertNotIn('ValueError', formatted_exc)
998        self.assertNotIn('TypeError', formatted_exc)
999        self.assertIn('\nStdout:\nset up\n', formatted_exc)
1000        self.assertNotIn('\ndo cleanup2\n', formatted_exc)
1001        self.assertNotIn('\ndo cleanup1\n', formatted_exc)
1002        test_case, formatted_exc = result.errors[1]
1003        self.assertEqual(str(test_case), description)
1004        self.assertIn('ValueError: bad cleanup2', formatted_exc)
1005        self.assertNotIn('ZeroDivisionError', formatted_exc)
1006        self.assertNotIn('TypeError', formatted_exc)
1007        self.assertIn('\nStdout:\nset up\ndo cleanup2\n', formatted_exc)
1008        self.assertNotIn('\ndo cleanup1\n', formatted_exc)
1009        test_case, formatted_exc = result.errors[2]
1010        self.assertEqual(str(test_case), description)
1011        self.assertIn('TypeError: bad cleanup1', formatted_exc)
1012        self.assertNotIn('ZeroDivisionError', formatted_exc)
1013        self.assertNotIn('ValueError', formatted_exc)
1014        self.assertIn(expected_out, formatted_exc)
1015
1016    def testBufferTearDown_DoCleanups(self):
1017        with captured_stdout() as stdout:
1018            result = unittest.TestResult()
1019        result.buffer = True
1020
1021        class Foo(unittest.TestCase):
1022            def setUp(self):
1023                print('set up')
1024                self.addCleanup(bad_cleanup1)
1025                self.addCleanup(bad_cleanup2)
1026            def tearDown(self):
1027                print('tear down')
1028                1/0
1029            def test_foo(self):
1030                pass
1031        suite = unittest.TestSuite([Foo('test_foo')])
1032        suite(result)
1033        expected_out = '\nStdout:\nset up\ntear down\ndo cleanup2\ndo cleanup1\n'
1034        self.assertEqual(stdout.getvalue(), expected_out)
1035        self.assertEqual(len(result.errors), 3)
1036        description = f'test_foo ({strclass(Foo)}.test_foo)'
1037        test_case, formatted_exc = result.errors[0]
1038        self.assertEqual(str(test_case), description)
1039        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
1040        self.assertNotIn('ValueError', formatted_exc)
1041        self.assertNotIn('TypeError', formatted_exc)
1042        self.assertIn('\nStdout:\nset up\ntear down\n', formatted_exc)
1043        self.assertNotIn('\ndo cleanup2\n', formatted_exc)
1044        self.assertNotIn('\ndo cleanup1\n', formatted_exc)
1045        test_case, formatted_exc = result.errors[1]
1046        self.assertEqual(str(test_case), description)
1047        self.assertIn('ValueError: bad cleanup2', formatted_exc)
1048        self.assertNotIn('ZeroDivisionError', formatted_exc)
1049        self.assertNotIn('TypeError', formatted_exc)
1050        self.assertIn('\nStdout:\nset up\ntear down\ndo cleanup2\n', formatted_exc)
1051        self.assertNotIn('\ndo cleanup1\n', formatted_exc)
1052        test_case, formatted_exc = result.errors[2]
1053        self.assertEqual(str(test_case), description)
1054        self.assertIn('TypeError: bad cleanup1', formatted_exc)
1055        self.assertNotIn('ZeroDivisionError', formatted_exc)
1056        self.assertNotIn('ValueError', formatted_exc)
1057        self.assertIn(expected_out, formatted_exc)
1058
1059    def testBufferSetupClass(self):
1060        with captured_stdout() as stdout:
1061            result = unittest.TestResult()
1062        result.buffer = True
1063
1064        class Foo(unittest.TestCase):
1065            @classmethod
1066            def setUpClass(cls):
1067                print('set up class')
1068                1/0
1069            def test_foo(self):
1070                pass
1071        suite = unittest.TestSuite([Foo('test_foo')])
1072        suite(result)
1073        expected_out = '\nStdout:\nset up class\n'
1074        self.assertEqual(stdout.getvalue(), expected_out)
1075        self.assertEqual(len(result.errors), 1)
1076        description = f'setUpClass ({strclass(Foo)})'
1077        test_case, formatted_exc = result.errors[0]
1078        self.assertEqual(test_case.description, description)
1079        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
1080        self.assertIn(expected_out, formatted_exc)
1081
1082    def testBufferTearDownClass(self):
1083        with captured_stdout() as stdout:
1084            result = unittest.TestResult()
1085        result.buffer = True
1086
1087        class Foo(unittest.TestCase):
1088            @classmethod
1089            def tearDownClass(cls):
1090                print('tear down class')
1091                1/0
1092            def test_foo(self):
1093                pass
1094        suite = unittest.TestSuite([Foo('test_foo')])
1095        suite(result)
1096        expected_out = '\nStdout:\ntear down class\n'
1097        self.assertEqual(stdout.getvalue(), expected_out)
1098        self.assertEqual(len(result.errors), 1)
1099        description = f'tearDownClass ({strclass(Foo)})'
1100        test_case, formatted_exc = result.errors[0]
1101        self.assertEqual(test_case.description, description)
1102        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
1103        self.assertIn(expected_out, formatted_exc)
1104
1105    def testBufferDoClassCleanups(self):
1106        with captured_stdout() as stdout:
1107            result = unittest.TestResult()
1108        result.buffer = True
1109
1110        class Foo(unittest.TestCase):
1111            @classmethod
1112            def setUpClass(cls):
1113                print('set up class')
1114                cls.addClassCleanup(bad_cleanup1)
1115                cls.addClassCleanup(bad_cleanup2)
1116            @classmethod
1117            def tearDownClass(cls):
1118                print('tear down class')
1119            def test_foo(self):
1120                pass
1121        suite = unittest.TestSuite([Foo('test_foo')])
1122        suite(result)
1123        expected_out = '\nStdout:\ntear down class\ndo cleanup2\ndo cleanup1\n'
1124        self.assertEqual(stdout.getvalue(), expected_out)
1125        self.assertEqual(len(result.errors), 2)
1126        description = f'tearDownClass ({strclass(Foo)})'
1127        test_case, formatted_exc = result.errors[0]
1128        self.assertEqual(test_case.description, description)
1129        self.assertIn('ValueError: bad cleanup2', formatted_exc)
1130        self.assertNotIn('TypeError', formatted_exc)
1131        self.assertIn(expected_out, formatted_exc)
1132        test_case, formatted_exc = result.errors[1]
1133        self.assertEqual(test_case.description, description)
1134        self.assertIn('TypeError: bad cleanup1', formatted_exc)
1135        self.assertNotIn('ValueError', formatted_exc)
1136        self.assertIn(expected_out, formatted_exc)
1137
1138    def testBufferSetupClass_DoClassCleanups(self):
1139        with captured_stdout() as stdout:
1140            result = unittest.TestResult()
1141        result.buffer = True
1142
1143        class Foo(unittest.TestCase):
1144            @classmethod
1145            def setUpClass(cls):
1146                print('set up class')
1147                cls.addClassCleanup(bad_cleanup1)
1148                cls.addClassCleanup(bad_cleanup2)
1149                1/0
1150            def test_foo(self):
1151                pass
1152        suite = unittest.TestSuite([Foo('test_foo')])
1153        suite(result)
1154        expected_out = '\nStdout:\nset up class\ndo cleanup2\ndo cleanup1\n'
1155        self.assertEqual(stdout.getvalue(), expected_out)
1156        self.assertEqual(len(result.errors), 3)
1157        description = f'setUpClass ({strclass(Foo)})'
1158        test_case, formatted_exc = result.errors[0]
1159        self.assertEqual(test_case.description, description)
1160        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
1161        self.assertNotIn('ValueError', formatted_exc)
1162        self.assertNotIn('TypeError', formatted_exc)
1163        self.assertIn('\nStdout:\nset up class\n', formatted_exc)
1164        test_case, formatted_exc = result.errors[1]
1165        self.assertEqual(test_case.description, description)
1166        self.assertIn('ValueError: bad cleanup2', formatted_exc)
1167        self.assertNotIn('ZeroDivisionError', formatted_exc)
1168        self.assertNotIn('TypeError', formatted_exc)
1169        self.assertIn(expected_out, formatted_exc)
1170        test_case, formatted_exc = result.errors[2]
1171        self.assertEqual(test_case.description, description)
1172        self.assertIn('TypeError: bad cleanup1', formatted_exc)
1173        self.assertNotIn('ZeroDivisionError', formatted_exc)
1174        self.assertNotIn('ValueError', formatted_exc)
1175        self.assertIn(expected_out, formatted_exc)
1176
1177    def testBufferTearDownClass_DoClassCleanups(self):
1178        with captured_stdout() as stdout:
1179            result = unittest.TestResult()
1180        result.buffer = True
1181
1182        class Foo(unittest.TestCase):
1183            @classmethod
1184            def setUpClass(cls):
1185                print('set up class')
1186                cls.addClassCleanup(bad_cleanup1)
1187                cls.addClassCleanup(bad_cleanup2)
1188            @classmethod
1189            def tearDownClass(cls):
1190                print('tear down class')
1191                1/0
1192            def test_foo(self):
1193                pass
1194        suite = unittest.TestSuite([Foo('test_foo')])
1195        suite(result)
1196        expected_out = '\nStdout:\ntear down class\ndo cleanup2\ndo cleanup1\n'
1197        self.assertEqual(stdout.getvalue(), expected_out)
1198        self.assertEqual(len(result.errors), 3)
1199        description = f'tearDownClass ({strclass(Foo)})'
1200        test_case, formatted_exc = result.errors[0]
1201        self.assertEqual(test_case.description, description)
1202        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
1203        self.assertNotIn('ValueError', formatted_exc)
1204        self.assertNotIn('TypeError', formatted_exc)
1205        self.assertIn('\nStdout:\ntear down class\n', formatted_exc)
1206        test_case, formatted_exc = result.errors[1]
1207        self.assertEqual(test_case.description, description)
1208        self.assertIn('ValueError: bad cleanup2', formatted_exc)
1209        self.assertNotIn('ZeroDivisionError', formatted_exc)
1210        self.assertNotIn('TypeError', formatted_exc)
1211        self.assertIn(expected_out, formatted_exc)
1212        test_case, formatted_exc = result.errors[2]
1213        self.assertEqual(test_case.description, description)
1214        self.assertIn('TypeError: bad cleanup1', formatted_exc)
1215        self.assertNotIn('ZeroDivisionError', formatted_exc)
1216        self.assertNotIn('ValueError', formatted_exc)
1217        self.assertIn(expected_out, formatted_exc)
1218
1219    def testBufferSetUpModule(self):
1220        with captured_stdout() as stdout:
1221            result = unittest.TestResult()
1222        result.buffer = True
1223
1224        class Foo(unittest.TestCase):
1225            def test_foo(self):
1226                pass
1227        class Module(object):
1228            @staticmethod
1229            def setUpModule():
1230                print('set up module')
1231                1/0
1232
1233        Foo.__module__ = 'Module'
1234        sys.modules['Module'] = Module
1235        self.addCleanup(sys.modules.pop, 'Module')
1236        suite = unittest.TestSuite([Foo('test_foo')])
1237        suite(result)
1238        expected_out = '\nStdout:\nset up module\n'
1239        self.assertEqual(stdout.getvalue(), expected_out)
1240        self.assertEqual(len(result.errors), 1)
1241        description = 'setUpModule (Module)'
1242        test_case, formatted_exc = result.errors[0]
1243        self.assertEqual(test_case.description, description)
1244        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
1245        self.assertIn(expected_out, formatted_exc)
1246
1247    def testBufferTearDownModule(self):
1248        with captured_stdout() as stdout:
1249            result = unittest.TestResult()
1250        result.buffer = True
1251
1252        class Foo(unittest.TestCase):
1253            def test_foo(self):
1254                pass
1255        class Module(object):
1256            @staticmethod
1257            def tearDownModule():
1258                print('tear down module')
1259                1/0
1260
1261        Foo.__module__ = 'Module'
1262        sys.modules['Module'] = Module
1263        self.addCleanup(sys.modules.pop, 'Module')
1264        suite = unittest.TestSuite([Foo('test_foo')])
1265        suite(result)
1266        expected_out = '\nStdout:\ntear down module\n'
1267        self.assertEqual(stdout.getvalue(), expected_out)
1268        self.assertEqual(len(result.errors), 1)
1269        description = 'tearDownModule (Module)'
1270        test_case, formatted_exc = result.errors[0]
1271        self.assertEqual(test_case.description, description)
1272        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
1273        self.assertIn(expected_out, formatted_exc)
1274
1275    def testBufferDoModuleCleanups(self):
1276        with captured_stdout() as stdout:
1277            result = unittest.TestResult()
1278        result.buffer = True
1279
1280        class Foo(unittest.TestCase):
1281            def test_foo(self):
1282                pass
1283        class Module(object):
1284            @staticmethod
1285            def setUpModule():
1286                print('set up module')
1287                unittest.addModuleCleanup(bad_cleanup1)
1288                unittest.addModuleCleanup(bad_cleanup2)
1289
1290        Foo.__module__ = 'Module'
1291        sys.modules['Module'] = Module
1292        self.addCleanup(sys.modules.pop, 'Module')
1293        suite = unittest.TestSuite([Foo('test_foo')])
1294        suite(result)
1295        expected_out = '\nStdout:\ndo cleanup2\ndo cleanup1\n'
1296        self.assertEqual(stdout.getvalue(), expected_out)
1297        self.assertEqual(len(result.errors), 1)
1298        description = 'tearDownModule (Module)'
1299        test_case, formatted_exc = result.errors[0]
1300        self.assertEqual(test_case.description, description)
1301        self.assertIn('ValueError: bad cleanup2', formatted_exc)
1302        self.assertNotIn('TypeError', formatted_exc)
1303        self.assertIn(expected_out, formatted_exc)
1304
1305    def testBufferSetUpModule_DoModuleCleanups(self):
1306        with captured_stdout() as stdout:
1307            result = unittest.TestResult()
1308        result.buffer = True
1309
1310        class Foo(unittest.TestCase):
1311            def test_foo(self):
1312                pass
1313        class Module(object):
1314            @staticmethod
1315            def setUpModule():
1316                print('set up module')
1317                unittest.addModuleCleanup(bad_cleanup1)
1318                unittest.addModuleCleanup(bad_cleanup2)
1319                1/0
1320
1321        Foo.__module__ = 'Module'
1322        sys.modules['Module'] = Module
1323        self.addCleanup(sys.modules.pop, 'Module')
1324        suite = unittest.TestSuite([Foo('test_foo')])
1325        suite(result)
1326        expected_out = '\nStdout:\nset up module\ndo cleanup2\ndo cleanup1\n'
1327        self.assertEqual(stdout.getvalue(), expected_out)
1328        self.assertEqual(len(result.errors), 2)
1329        description = 'setUpModule (Module)'
1330        test_case, formatted_exc = result.errors[0]
1331        self.assertEqual(test_case.description, description)
1332        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
1333        self.assertNotIn('ValueError', formatted_exc)
1334        self.assertNotIn('TypeError', formatted_exc)
1335        self.assertIn('\nStdout:\nset up module\n', formatted_exc)
1336        test_case, formatted_exc = result.errors[1]
1337        self.assertIn(expected_out, formatted_exc)
1338        self.assertEqual(test_case.description, description)
1339        self.assertIn('ValueError: bad cleanup2', formatted_exc)
1340        self.assertNotIn('ZeroDivisionError', formatted_exc)
1341        self.assertNotIn('TypeError', formatted_exc)
1342        self.assertIn(expected_out, formatted_exc)
1343
1344    def testBufferTearDownModule_DoModuleCleanups(self):
1345        with captured_stdout() as stdout:
1346            result = unittest.TestResult()
1347        result.buffer = True
1348
1349        class Foo(unittest.TestCase):
1350            def test_foo(self):
1351                pass
1352        class Module(object):
1353            @staticmethod
1354            def setUpModule():
1355                print('set up module')
1356                unittest.addModuleCleanup(bad_cleanup1)
1357                unittest.addModuleCleanup(bad_cleanup2)
1358            @staticmethod
1359            def tearDownModule():
1360                print('tear down module')
1361                1/0
1362
1363        Foo.__module__ = 'Module'
1364        sys.modules['Module'] = Module
1365        self.addCleanup(sys.modules.pop, 'Module')
1366        suite = unittest.TestSuite([Foo('test_foo')])
1367        suite(result)
1368        expected_out = '\nStdout:\ntear down module\ndo cleanup2\ndo cleanup1\n'
1369        self.assertEqual(stdout.getvalue(), expected_out)
1370        self.assertEqual(len(result.errors), 2)
1371        description = 'tearDownModule (Module)'
1372        test_case, formatted_exc = result.errors[0]
1373        self.assertEqual(test_case.description, description)
1374        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
1375        self.assertNotIn('ValueError', formatted_exc)
1376        self.assertNotIn('TypeError', formatted_exc)
1377        self.assertIn('\nStdout:\ntear down module\n', formatted_exc)
1378        test_case, formatted_exc = result.errors[1]
1379        self.assertEqual(test_case.description, description)
1380        self.assertIn('ValueError: bad cleanup2', formatted_exc)
1381        self.assertNotIn('ZeroDivisionError', formatted_exc)
1382        self.assertNotIn('TypeError', formatted_exc)
1383        self.assertIn(expected_out, formatted_exc)
1384
1385
1386if __name__ == '__main__':
1387    unittest.main()
1388