note there are not separate tests for testresult wassuccessful testresult errors testresult failures testresult testsrun or testresult shouldstop because these only have meaning in terms of other testresult methods accordingly tests for the aforenamed attributes are incorporated in with the tests for the defining methods this method can be called to signal that the set of tests being run should be aborted by setting the testresult s shouldstop attribute to true called when the test case test is about to be run the default implementation simply increments the instance s testsrun counter called after the test case test has been executed regardless of the outcome the default implementation does nothing same tests as above make sure nothing has changed called before and after tests are run the default implementation does nothing addsuccesstest called when the test case test succeeds wassuccessful returns true if all tests run so far have passed otherwise returns false testsrun the total number of tests run so far errors a list containing 2tuples of testcase instances and formatted tracebacks each tuple represents a test which raised an unexpected exception contains formatted tracebacks instead of sys excinfo results failures a list containing 2tuples of testcase instances and formatted tracebacks each tuple represents a test where a failure was explicitly signalled using the testcase fail or testcase assert methods contains formatted tracebacks instead of sys excinfo results addfailuretest err called when the test case test signals a failure err is a tuple of the form returned by sys excinfo type value traceback wassuccessful returns true if all tests run so far have passed otherwise returns false testsrun the total number of tests run so far errors a list containing 2tuples of testcase instances and formatted tracebacks each tuple represents a test which raised an unexpected exception contains formatted tracebacks instead of sys excinfo results failures a list containing 2tuples of testcase instances and formatted tracebacks each tuple represents a test where a failure was explicitly signalled using the testcase fail or testcase assert methods contains formatted tracebacks instead of sys excinfo results create two directionally opposed cycles cause in one direction context in the other adderrortest err called when the test case test raises an unexpected exception err is a tuple of the form returned by sys excinfo type value traceback wassuccessful returns true if all tests run so far have passed otherwise returns false testsrun the total number of tests run so far errors a list containing 2tuples of testcase instances and formatted tracebacks each tuple represents a test which raised an unexpected exception contains formatted tracebacks instead of sys excinfo results failures a list containing 2tuples of testcase instances and formatted tracebacks each tuple represents a test where a failure was explicitly signalled using the testcase fail or testcase assert methods contains formatted tracebacks instead of sys excinfo results register an error by hand to check the api now trigger a failure tests getdescription for a method with a docstring result unittest texttestresultnone true 1 self assertequal result getdescriptionself testgetdescriptionwithonelinedocstring name testtexttestresult testgetdescriptionwithonelinedocstringn tests getdescription for a method with a docstring unittest skipifsys flags optimize 2 docstrings are omitted with o2 and above def testgetsubtestdescriptionwithonelinedocstringself tests getdescription for a method with a longer docstring the second line of the docstring tests getdescription for a method with a longer docstring the second line of the docstring this will raise an exception if texttestrunner can t handle old test result objects expectederrmessage if includeerror expectederrmessage textwrap dedent stderr bar note there are not separate tests for testresult wassuccessful testresult errors testresult failures testresult testsrun or testresult shouldstop because these only have meaning in terms of other testresult methods accordingly tests for the aforenamed attributes are incorporated in with the tests for the defining methods this method can be called to signal that the set of tests being run should be aborted by setting the testresult s shouldstop attribute to true called when the test case test is about to be run the default implementation simply increments the instance s testsrun counter called after the test case test has been executed regardless of the outcome the default implementation does nothing same tests as above make sure nothing has changed called before and after tests are run the default implementation does nothing addsuccess test called when the test case test succeeds wassuccessful returns true if all tests run so far have passed otherwise returns false testsrun the total number of tests run so far errors a list containing 2 tuples of testcase instances and formatted tracebacks each tuple represents a test which raised an unexpected exception contains formatted tracebacks instead of sys exc_info results failures a list containing 2 tuples of testcase instances and formatted tracebacks each tuple represents a test where a failure was explicitly signalled using the testcase fail or testcase assert methods contains formatted tracebacks instead of sys exc_info results addfailure test err called when the test case test signals a failure err is a tuple of the form returned by sys exc_info type value traceback wassuccessful returns true if all tests run so far have passed otherwise returns false testsrun the total number of tests run so far errors a list containing 2 tuples of testcase instances and formatted tracebacks each tuple represents a test which raised an unexpected exception contains formatted tracebacks instead of sys exc_info results failures a list containing 2 tuples of testcase instances and formatted tracebacks each tuple represents a test where a failure was explicitly signalled using the testcase fail or testcase assert methods contains formatted tracebacks instead of sys exc_info results create two directionally opposed cycles __cause__ in one direction __context__ in the other adderror test err called when the test case test raises an unexpected exception err is a tuple of the form returned by sys exc_info type value traceback wassuccessful returns true if all tests run so far have passed otherwise returns false testsrun the total number of tests run so far errors a list containing 2 tuples of testcase instances and formatted tracebacks each tuple represents a test which raised an unexpected exception contains formatted tracebacks instead of sys exc_info results failures a list containing 2 tuples of testcase instances and formatted tracebacks each tuple represents a test where a failure was explicitly signalled using the testcase fail or testcase assert methods contains formatted tracebacks instead of sys exc_info results register an error by hand to check the api now trigger a failure tests getdescription for a method with a docstring tests getdescription for a method with a docstring tests getdescription for a method with a longer docstring the second line of the docstring tests getdescription for a method with a longer docstring the second line of the docstring this will raise an exception if texttestrunner can t handle old test result objects stdout foo stderr bar
import io
import sys
import textwrap

from test.support import warnings_helper, captured_stdout

import traceback
import unittest
from unittest.util import strclass
from test.test_unittest.support import BufferedWriter


class MockTraceback(object):
    class TracebackException:
        def __init__(self, *args, **kwargs):
            self.capture_locals = kwargs.get('capture_locals', False)
        def format(self):
            result = ['A traceback']
            if self.capture_locals:
                result.append('locals')
            return result

def restore_traceback():
    unittest.result.traceback = traceback


def bad_cleanup1():
    print('do cleanup1')
    raise TypeError('bad cleanup1')


def bad_cleanup2():
    print('do cleanup2')
    raise ValueError('bad cleanup2')


class Test_TestResult(unittest.TestCase):
    
    
    
    
    
    
    
    

    def test_init(self):
        result = unittest.TestResult()

        self.assertTrue(result.wasSuccessful())
        self.assertEqual(len(result.errors), 0)
        self.assertEqual(len(result.failures), 0)
        self.assertEqual(result.testsRun, 0)
        self.assertEqual(result.shouldStop, False)
        self.assertIsNone(result._stdout_buffer)
        self.assertIsNone(result._stderr_buffer)

    
    
    
    def test_stop(self):
        result = unittest.TestResult()

        result.stop()

        self.assertEqual(result.shouldStop, True)

    
    
    def test_startTest(self):
        class Foo(unittest.TestCase):
            def test_1(self):
                pass

        test = Foo('test_1')

        result = unittest.TestResult()

        result.startTest(test)

        self.assertTrue(result.wasSuccessful())
        self.assertEqual(len(result.errors), 0)
        self.assertEqual(len(result.failures), 0)
        self.assertEqual(result.testsRun, 1)
        self.assertEqual(result.shouldStop, False)

        result.stopTest(test)

    
    
    def test_stopTest(self):
        class Foo(unittest.TestCase):
            def test_1(self):
                pass

        test = Foo('test_1')

        result = unittest.TestResult()

        result.startTest(test)

        self.assertTrue(result.wasSuccessful())
        self.assertEqual(len(result.errors), 0)
        self.assertEqual(len(result.failures), 0)
        self.assertEqual(result.testsRun, 1)
        self.assertEqual(result.shouldStop, False)

        result.stopTest(test)

        
        self.assertTrue(result.wasSuccessful())
        self.assertEqual(len(result.errors), 0)
        self.assertEqual(len(result.failures), 0)
        self.assertEqual(result.testsRun, 1)
        self.assertEqual(result.shouldStop, False)

    
    def test_startTestRun_stopTestRun(self):
        result = unittest.TestResult()
        result.startTestRun()
        result.stopTestRun()

    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    def test_addSuccess(self):
        class Foo(unittest.TestCase):
            def test_1(self):
                pass

        test = Foo('test_1')

        result = unittest.TestResult()

        result.startTest(test)
        result.addSuccess(test)
        result.stopTest(test)

        self.assertTrue(result.wasSuccessful())
        self.assertEqual(len(result.errors), 0)
        self.assertEqual(len(result.failures), 0)
        self.assertEqual(result.testsRun, 1)
        self.assertEqual(result.shouldStop, False)

    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    def test_addFailure(self):
        class Foo(unittest.TestCase):
            def test_1(self):
                pass

        test = Foo('test_1')
        try:
            test.fail("foo")
        except:
            exc_info_tuple = sys.exc_info()

        result = unittest.TestResult()

        result.startTest(test)
        result.addFailure(test, exc_info_tuple)
        result.stopTest(test)

        self.assertFalse(result.wasSuccessful())
        self.assertEqual(len(result.errors), 0)
        self.assertEqual(len(result.failures), 1)
        self.assertEqual(result.testsRun, 1)
        self.assertEqual(result.shouldStop, False)

        test_case, formatted_exc = result.failures[0]
        self.assertIs(test_case, test)
        self.assertIsInstance(formatted_exc, str)

    def test_addFailure_filter_traceback_frames(self):
        class Foo(unittest.TestCase):
            def test_1(self):
                pass

        test = Foo('test_1')
        def get_exc_info():
            try:
                test.fail("foo")
            except:
                return sys.exc_info()

        exc_info_tuple = get_exc_info()

        full_exc = traceback.format_exception(*exc_info_tuple)

        result = unittest.TestResult()
        result.startTest(test)
        result.addFailure(test, exc_info_tuple)
        result.stopTest(test)

        formatted_exc = result.failures[0][1]
        dropped = [l for l in full_exc if l not in formatted_exc]
        self.assertEqual(len(dropped), 1)
        self.assertIn("raise self.failureException(msg)", dropped[0])

    def test_addFailure_filter_traceback_frames_context(self):
        class Foo(unittest.TestCase):
            def test_1(self):
                pass

        test = Foo('test_1')
        def get_exc_info():
            try:
                try:
                    test.fail("foo")
                except:
                    raise ValueError(42)
            except:
                return sys.exc_info()

        exc_info_tuple = get_exc_info()

        full_exc = traceback.format_exception(*exc_info_tuple)

        result = unittest.TestResult()
        result.startTest(test)
        result.addFailure(test, exc_info_tuple)
        result.stopTest(test)

        formatted_exc = result.failures[0][1]
        dropped = [l for l in full_exc if l not in formatted_exc]
        self.assertEqual(len(dropped), 1)
        self.assertIn("raise self.failureException(msg)", dropped[0])

    def test_addFailure_filter_traceback_frames_chained_exception_self_loop(self):
        class Foo(unittest.TestCase):
            def test_1(self):
                pass

        def get_exc_info():
            try:
                loop = Exception("Loop")
                loop.__cause__ = loop
                loop.__context__ = loop
                raise loop
            except:
                return sys.exc_info()

        exc_info_tuple = get_exc_info()

        test = Foo('test_1')
        result = unittest.TestResult()
        result.startTest(test)
        result.addFailure(test, exc_info_tuple)
        result.stopTest(test)

        formatted_exc = result.failures[0][1]
        self.assertEqual(formatted_exc.count("Exception: Loop\n"), 1)

    def test_addFailure_filter_traceback_frames_chained_exception_cycle(self):
        class Foo(unittest.TestCase):
            def test_1(self):
                pass

        def get_exc_info():
            try:
                
                
                A, B, C = Exception("A"), Exception("B"), Exception("C")
                edges = [(C, B), (B, A), (A, C)]
                for ex1, ex2 in edges:
                    ex1.__cause__ = ex2
                    ex2.__context__ = ex1
                raise C
            except:
                return sys.exc_info()

        exc_info_tuple = get_exc_info()

        test = Foo('test_1')
        result = unittest.TestResult()
        result.startTest(test)
        result.addFailure(test, exc_info_tuple)
        result.stopTest(test)

        formatted_exc = result.failures[0][1]
        self.assertEqual(formatted_exc.count("Exception: A\n"), 1)
        self.assertEqual(formatted_exc.count("Exception: B\n"), 1)
        self.assertEqual(formatted_exc.count("Exception: C\n"), 1)

    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    def test_addError(self):
        class Foo(unittest.TestCase):
            def test_1(self):
                pass

        test = Foo('test_1')
        try:
            raise TypeError()
        except:
            exc_info_tuple = sys.exc_info()

        result = unittest.TestResult()

        result.startTest(test)
        result.addError(test, exc_info_tuple)
        result.stopTest(test)

        self.assertFalse(result.wasSuccessful())
        self.assertEqual(len(result.errors), 1)
        self.assertEqual(len(result.failures), 0)
        self.assertEqual(result.testsRun, 1)
        self.assertEqual(result.shouldStop, False)

        test_case, formatted_exc = result.errors[0]
        self.assertIs(test_case, test)
        self.assertIsInstance(formatted_exc, str)

    def test_addError_locals(self):
        class Foo(unittest.TestCase):
            def test_1(self):
                1/0

        test = Foo('test_1')
        result = unittest.TestResult()
        result.tb_locals = True

        unittest.result.traceback = MockTraceback
        self.addCleanup(restore_traceback)
        result.startTestRun()
        test.run(result)
        result.stopTestRun()

        self.assertEqual(len(result.errors), 1)
        test_case, formatted_exc = result.errors[0]
        self.assertEqual('A tracebacklocals', formatted_exc)

    def test_addSubTest(self):
        class Foo(unittest.TestCase):
            def test_1(self):
                nonlocal subtest
                with self.subTest(foo=1):
                    subtest = self._subtest
                    try:
                        1/0
                    except ZeroDivisionError:
                        exc_info_tuple = sys.exc_info()
                    
                    result.addSubTest(test, subtest, exc_info_tuple)
                    
                    self.fail("some recognizable failure")

        subtest = None
        test = Foo('test_1')
        result = unittest.TestResult()

        test.run(result)

        self.assertFalse(result.wasSuccessful())
        self.assertEqual(len(result.errors), 1)
        self.assertEqual(len(result.failures), 1)
        self.assertEqual(result.testsRun, 1)
        self.assertEqual(result.shouldStop, False)

        test_case, formatted_exc = result.errors[0]
        self.assertIs(test_case, subtest)
        self.assertIn("ZeroDivisionError", formatted_exc)
        test_case, formatted_exc = result.failures[0]
        self.assertIs(test_case, subtest)
        self.assertIn("some recognizable failure", formatted_exc)

    def testStackFrameTrimming(self):
        class Frame(object):
            class tb_frame(object):
                f_globals = {}
        result = unittest.TestResult()
        self.assertFalse(result._is_relevant_tb_level(Frame))

        Frame.tb_frame.f_globals['__unittest'] = True
        self.assertTrue(result._is_relevant_tb_level(Frame))

    def testFailFast(self):
        result = unittest.TestResult()
        result._exc_info_to_string = lambda *_: ''
        result.failfast = True
        result.addError(None, None)
        self.assertTrue(result.shouldStop)

        result = unittest.TestResult()
        result._exc_info_to_string = lambda *_: ''
        result.failfast = True
        result.addFailure(None, None)
        self.assertTrue(result.shouldStop)

        result = unittest.TestResult()
        result._exc_info_to_string = lambda *_: ''
        result.failfast = True
        result.addUnexpectedSuccess(None)
        self.assertTrue(result.shouldStop)

    def testFailFastSetByRunner(self):
        stream = BufferedWriter()
        runner = unittest.TextTestRunner(stream=stream, failfast=True)
        def test(result):
            result.testsRun += 1
            self.assertTrue(result.failfast)
        result = runner.run(test)
        stream.flush()
        self.assertTrue(stream.getvalue().endswith('\n\nOK\n'))


class Test_TextTestResult(unittest.TestCase):
    maxDiff = None

    def testGetDescriptionWithoutDocstring(self):
        result = unittest.TextTestResult(None, True, 1)
        self.assertEqual(
                result.getDescription(self),
                'testGetDescriptionWithoutDocstring (' + __name__ +
                '.Test_TextTestResult.testGetDescriptionWithoutDocstring)')

    def testGetSubTestDescriptionWithoutDocstring(self):
        with self.subTest(foo=1, bar=2):
            result = unittest.TextTestResult(None, True, 1)
            self.assertEqual(
                    result.getDescription(self._subtest),
                    'testGetSubTestDescriptionWithoutDocstring (' + __name__ +
                    '.Test_TextTestResult.testGetSubTestDescriptionWithoutDocstring) (foo=1, bar=2)')

        with self.subTest('some message'):
            result = unittest.TextTestResult(None, True, 1)
            self.assertEqual(
                    result.getDescription(self._subtest),
                    'testGetSubTestDescriptionWithoutDocstring (' + __name__ +
                    '.Test_TextTestResult.testGetSubTestDescriptionWithoutDocstring) [some message]')

    def testGetSubTestDescriptionWithoutDocstringAndParams(self):
        with self.subTest():
            result = unittest.TextTestResult(None, True, 1)
            self.assertEqual(
                    result.getDescription(self._subtest),
                    'testGetSubTestDescriptionWithoutDocstringAndParams '
                    '(' + __name__ + '.Test_TextTestResult.testGetSubTestDescriptionWithoutDocstringAndParams) '
                    '(<subtest>)')

    def testGetSubTestDescriptionForFalseValues(self):
        expected = 'testGetSubTestDescriptionForFalseValues (%s.Test_TextTestResult.testGetSubTestDescriptionForFalseValues) [%s]'
        result = unittest.TextTestResult(None, True, 1)
        for arg in [0, None, []]:
            with self.subTest(arg):
                self.assertEqual(
                    result.getDescription(self._subtest),
                    expected % (__name__, arg)
                )

    def testGetNestedSubTestDescriptionWithoutDocstring(self):
        with self.subTest(foo=1):
            with self.subTest(baz=2, bar=3):
                result = unittest.TextTestResult(None, True, 1)
                self.assertEqual(
                        result.getDescription(self._subtest),
                        'testGetNestedSubTestDescriptionWithoutDocstring '
                        '(' + __name__ + '.Test_TextTestResult.testGetNestedSubTestDescriptionWithoutDocstring) '
                        '(baz=2, bar=3, foo=1)')

    def testGetDuplicatedNestedSubTestDescriptionWithoutDocstring(self):
        with self.subTest(foo=1, bar=2):
            with self.subTest(baz=3, bar=4):
                result = unittest.TextTestResult(None, True, 1)
                self.assertEqual(
                        result.getDescription(self._subtest),
                        'testGetDuplicatedNestedSubTestDescriptionWithoutDocstring '
                        '(' + __name__ + '.Test_TextTestResult.testGetDuplicatedNestedSubTestDescriptionWithoutDocstring) (baz=3, bar=4, foo=1)')

    @unittest.skipIf(sys.flags.optimize >= 2,
                     "Docstrings are omitted with -O2 and above")
    def testGetDescriptionWithOneLineDocstring(self):
        
        result = unittest.TextTestResult(None, True, 1)
        self.assertEqual(
                result.getDescription(self),
               ('testGetDescriptionWithOneLineDocstring '
                '(' + __name__ + '.Test_TextTestResult.testGetDescriptionWithOneLineDocstring)\n'
                'Tests getDescription() for a method with a docstring.'))

    @unittest.skipIf(sys.flags.optimize >= 2,
                     "Docstrings are omitted with -O2 and above")
    def testGetSubTestDescriptionWithOneLineDocstring(self):
        
        result = unittest.TextTestResult(None, True, 1)
        with self.subTest(foo=1, bar=2):
            self.assertEqual(
                result.getDescription(self._subtest),
               ('testGetSubTestDescriptionWithOneLineDocstring '
                '(' + __name__ + '.Test_TextTestResult.testGetSubTestDescriptionWithOneLineDocstring) '
                '(foo=1, bar=2)\n'

                'Tests getDescription() for a method with a docstring.'))

    @unittest.skipIf(sys.flags.optimize >= 2,
                     "Docstrings are omitted with -O2 and above")
    def testGetDescriptionWithMultiLineDocstring(self):
        
        result = unittest.TextTestResult(None, True, 1)
        self.assertEqual(
                result.getDescription(self),
               ('testGetDescriptionWithMultiLineDocstring '
                '(' + __name__ + '.Test_TextTestResult.testGetDescriptionWithMultiLineDocstring)\n'
                'Tests getDescription() for a method with a longer '
                'docstring.'))

    @unittest.skipIf(sys.flags.optimize >= 2,
                     "Docstrings are omitted with -O2 and above")
    def testGetSubTestDescriptionWithMultiLineDocstring(self):
        
        result = unittest.TextTestResult(None, True, 1)
        with self.subTest(foo=1, bar=2):
            self.assertEqual(
                result.getDescription(self._subtest),
               ('testGetSubTestDescriptionWithMultiLineDocstring '
                '(' + __name__ + '.Test_TextTestResult.testGetSubTestDescriptionWithMultiLineDocstring) '
                '(foo=1, bar=2)\n'
                'Tests getDescription() for a method with a longer '
                'docstring.'))

    class Test(unittest.TestCase):
        def testSuccess(self):
            pass
        def testSkip(self):
            self.skipTest('skip')
        def testFail(self):
            self.fail('fail')
        def testError(self):
            raise Exception('error')
        @unittest.expectedFailure
        def testExpectedFailure(self):
            self.fail('fail')
        @unittest.expectedFailure
        def testUnexpectedSuccess(self):
            pass
        def testSubTestSuccess(self):
            with self.subTest('one', a=1):
                pass
            with self.subTest('two', b=2):
                pass
        def testSubTestMixed(self):
            with self.subTest('success', a=1):
                pass
            with self.subTest('skip', b=2):
                self.skipTest('skip')
            with self.subTest('fail', c=3):
                self.fail('fail')
            with self.subTest('error', d=4):
                raise Exception('error')

        tearDownError = None
        def tearDown(self):
            if self.tearDownError is not None:
                raise self.tearDownError

    def _run_test(self, test_name, verbosity, tearDownError=None):
        stream = BufferedWriter()
        stream = unittest.runner._WritelnDecorator(stream)
        result = unittest.TextTestResult(stream, True, verbosity)
        test = self.Test(test_name)
        test.tearDownError = tearDownError
        test.run(result)
        return stream.getvalue()

    def testDotsOutput(self):
        self.assertEqual(self._run_test('testSuccess', 1), '.')
        self.assertEqual(self._run_test('testSkip', 1), 's')
        self.assertEqual(self._run_test('testFail', 1), 'F')
        self.assertEqual(self._run_test('testError', 1), 'E')
        self.assertEqual(self._run_test('testExpectedFailure', 1), 'x')
        self.assertEqual(self._run_test('testUnexpectedSuccess', 1), 'u')

    def testLongOutput(self):
        classname = f'{__name__}.{self.Test.__qualname__}'
        self.assertEqual(self._run_test('testSuccess', 2),
                         f'testSuccess ({classname}.testSuccess) ... ok\n')
        self.assertEqual(self._run_test('testSkip', 2),
                         f"testSkip ({classname}.testSkip) ... skipped 'skip'\n")
        self.assertEqual(self._run_test('testFail', 2),
                         f'testFail ({classname}.testFail) ... FAIL\n')
        self.assertEqual(self._run_test('testError', 2),
                         f'testError ({classname}.testError) ... ERROR\n')
        self.assertEqual(self._run_test('testExpectedFailure', 2),
                         f'testExpectedFailure ({classname}.testExpectedFailure) ... expected failure\n')
        self.assertEqual(self._run_test('testUnexpectedSuccess', 2),
                         f'testUnexpectedSuccess ({classname}.testUnexpectedSuccess) ... unexpected success\n')

    def testDotsOutputSubTestSuccess(self):
        self.assertEqual(self._run_test('testSubTestSuccess', 1), '.')

    def testLongOutputSubTestSuccess(self):
        classname = f'{__name__}.{self.Test.__qualname__}'
        self.assertEqual(self._run_test('testSubTestSuccess', 2),
                         f'testSubTestSuccess ({classname}.testSubTestSuccess) ... ok\n')

    def testDotsOutputSubTestMixed(self):
        self.assertEqual(self._run_test('testSubTestMixed', 1), 'sFE')

    def testLongOutputSubTestMixed(self):
        classname = f'{__name__}.{self.Test.__qualname__}'
        self.assertEqual(self._run_test('testSubTestMixed', 2),
                f'testSubTestMixed ({classname}.testSubTestMixed) ... \n'
                f"  testSubTestMixed ({classname}.testSubTestMixed) [skip] (b=2) ... skipped 'skip'\n"
                f'  testSubTestMixed ({classname}.testSubTestMixed) [fail] (c=3) ... FAIL\n'
                f'  testSubTestMixed ({classname}.testSubTestMixed) [error] (d=4) ... ERROR\n')

    def testDotsOutputTearDownFail(self):
        out = self._run_test('testSuccess', 1, AssertionError('fail'))
        self.assertEqual(out, 'F')
        out = self._run_test('testError', 1, AssertionError('fail'))
        self.assertEqual(out, 'EF')
        out = self._run_test('testFail', 1, Exception('error'))
        self.assertEqual(out, 'FE')
        out = self._run_test('testSkip', 1, AssertionError('fail'))
        self.assertEqual(out, 'sF')

    def testLongOutputTearDownFail(self):
        classname = f'{__name__}.{self.Test.__qualname__}'
        out = self._run_test('testSuccess', 2, AssertionError('fail'))
        self.assertEqual(out,
                         f'testSuccess ({classname}.testSuccess) ... FAIL\n')
        out = self._run_test('testError', 2, AssertionError('fail'))
        self.assertEqual(out,
                         f'testError ({classname}.testError) ... ERROR\n'
                         f'testError ({classname}.testError) ... FAIL\n')
        out = self._run_test('testFail', 2, Exception('error'))
        self.assertEqual(out,
                         f'testFail ({classname}.testFail) ... FAIL\n'
                         f'testFail ({classname}.testFail) ... ERROR\n')
        out = self._run_test('testSkip', 2, AssertionError('fail'))
        self.assertEqual(out,
                         f"testSkip ({classname}.testSkip) ... skipped 'skip'\n"
                         f'testSkip ({classname}.testSkip) ... FAIL\n')


classDict = dict(unittest.TestResult.__dict__)
for m in ('addSkip', 'addExpectedFailure', 'addUnexpectedSuccess',
           '__init__'):
    del classDict[m]

def __init__(self, stream=None, descriptions=None, verbosity=None):
    self.failures = []
    self.errors = []
    self.testsRun = 0
    self.shouldStop = False
    self.buffer = False
    self.tb_locals = False

classDict['__init__'] = __init__
OldResult = type('OldResult', (object,), classDict)

class Test_OldTestResult(unittest.TestCase):

    def assertOldResultWarning(self, test, failures):
        with warnings_helper.check_warnings(
                ("TestResult has no add.+ method,", RuntimeWarning)):
            result = OldResult()
            test.run(result)
            self.assertEqual(len(result.failures), failures)

    def testOldTestResult(self):
        class Test(unittest.TestCase):
            def testSkip(self):
                self.skipTest('foobar')
            @unittest.expectedFailure
            def testExpectedFail(self):
                raise TypeError
            @unittest.expectedFailure
            def testUnexpectedSuccess(self):
                pass

        for test_name, should_pass in (('testSkip', True),
                                       ('testExpectedFail', True),
                                       ('testUnexpectedSuccess', False)):
            test = Test(test_name)
            self.assertOldResultWarning(test, int(not should_pass))

    def testOldTestTesultSetup(self):
        class Test(unittest.TestCase):
            def setUp(self):
                self.skipTest('no reason')
            def testFoo(self):
                pass
        self.assertOldResultWarning(Test('testFoo'), 0)

    def testOldTestResultClass(self):
        @unittest.skip('no reason')
        class Test(unittest.TestCase):
            def testFoo(self):
                pass
        self.assertOldResultWarning(Test('testFoo'), 0)

    def testOldResultWithRunner(self):
        class Test(unittest.TestCase):
            def testFoo(self):
                pass
        runner = unittest.TextTestRunner(resultclass=OldResult,
                                          stream=io.StringIO())
        
        
        runner.run(Test('testFoo'))


class TestOutputBuffering(unittest.TestCase):

    def setUp(self):
        self._real_out = sys.stdout
        self._real_err = sys.stderr

    def tearDown(self):
        sys.stdout = self._real_out
        sys.stderr = self._real_err

    def testBufferOutputOff(self):
        real_out = self._real_out
        real_err = self._real_err

        result = unittest.TestResult()
        self.assertFalse(result.buffer)

        self.assertIs(real_out, sys.stdout)
        self.assertIs(real_err, sys.stderr)

        result.startTest(self)

        self.assertIs(real_out, sys.stdout)
        self.assertIs(real_err, sys.stderr)

    def testBufferOutputStartTestAddSuccess(self):
        real_out = self._real_out
        real_err = self._real_err

        result = unittest.TestResult()
        self.assertFalse(result.buffer)

        result.buffer = True

        self.assertIs(real_out, sys.stdout)
        self.assertIs(real_err, sys.stderr)

        result.startTest(self)

        self.assertIsNot(real_out, sys.stdout)
        self.assertIsNot(real_err, sys.stderr)
        self.assertIsInstance(sys.stdout, io.StringIO)
        self.assertIsInstance(sys.stderr, io.StringIO)
        self.assertIsNot(sys.stdout, sys.stderr)

        out_stream = sys.stdout
        err_stream = sys.stderr

        result._original_stdout = io.StringIO()
        result._original_stderr = io.StringIO()

        print('foo')
        print('bar', file=sys.stderr)

        self.assertEqual(out_stream.getvalue(), 'foo\n')
        self.assertEqual(err_stream.getvalue(), 'bar\n')

        self.assertEqual(result._original_stdout.getvalue(), '')
        self.assertEqual(result._original_stderr.getvalue(), '')

        result.addSuccess(self)
        result.stopTest(self)

        self.assertIs(sys.stdout, result._original_stdout)
        self.assertIs(sys.stderr, result._original_stderr)

        self.assertEqual(result._original_stdout.getvalue(), '')
        self.assertEqual(result._original_stderr.getvalue(), '')

        self.assertEqual(out_stream.getvalue(), '')
        self.assertEqual(err_stream.getvalue(), '')


    def getStartedResult(self):
        result = unittest.TestResult()
        result.buffer = True
        result.startTest(self)
        return result

    def testBufferOutputAddErrorOrFailure(self):
        unittest.result.traceback = MockTraceback
        self.addCleanup(restore_traceback)

        for message_attr, add_attr, include_error in [
            ('errors', 'addError', True),
            ('failures', 'addFailure', False),
            ('errors', 'addError', True),
            ('failures', 'addFailure', False)
        ]:
            result = self.getStartedResult()
            buffered_out = sys.stdout
            buffered_err = sys.stderr
            result._original_stdout = io.StringIO()
            result._original_stderr = io.StringIO()

            print('foo', file=sys.stdout)
            if include_error:
                print('bar', file=sys.stderr)


            addFunction = getattr(result, add_attr)
            addFunction(self, (None, None, None))
            result.stopTest(self)

            result_list = getattr(result, message_attr)
            self.assertEqual(len(result_list), 1)

            test, message = result_list[0]
            expectedOutMessage = textwrap.dedent()
            expectedErrMessage = ''
            if include_error:
                expectedErrMessage = textwrap.dedent()

            expectedFullMessage = 'A traceback%s%s' % (expectedOutMessage, expectedErrMessage)

            self.assertIs(test, self)
            self.assertEqual(result._original_stdout.getvalue(), expectedOutMessage)
            self.assertEqual(result._original_stderr.getvalue(), expectedErrMessage)
            self.assertMultiLineEqual(message, expectedFullMessage)

    def testBufferSetUp(self):
        with captured_stdout() as stdout:
            result = unittest.TestResult()
        result.buffer = True

        class Foo(unittest.TestCase):
            def setUp(self):
                print('set up')
                1/0
            def test_foo(self):
                pass
        suite = unittest.TestSuite([Foo('test_foo')])
        suite(result)
        expected_out = '\nStdout:\nset up\n'
        self.assertEqual(stdout.getvalue(), expected_out)
        self.assertEqual(len(result.errors), 1)
        description = f'test_foo ({strclass(Foo)}.test_foo)'
        test_case, formatted_exc = result.errors[0]
        self.assertEqual(str(test_case), description)
        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
        self.assertIn(expected_out, formatted_exc)

    def testBufferTearDown(self):
        with captured_stdout() as stdout:
            result = unittest.TestResult()
        result.buffer = True

        class Foo(unittest.TestCase):
            def tearDown(self):
                print('tear down')
                1/0
            def test_foo(self):
                pass
        suite = unittest.TestSuite([Foo('test_foo')])
        suite(result)
        expected_out = '\nStdout:\ntear down\n'
        self.assertEqual(stdout.getvalue(), expected_out)
        self.assertEqual(len(result.errors), 1)
        description = f'test_foo ({strclass(Foo)}.test_foo)'
        test_case, formatted_exc = result.errors[0]
        self.assertEqual(str(test_case), description)
        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
        self.assertIn(expected_out, formatted_exc)

    def testBufferDoCleanups(self):
        with captured_stdout() as stdout:
            result = unittest.TestResult()
        result.buffer = True

        class Foo(unittest.TestCase):
            def setUp(self):
                print('set up')
                self.addCleanup(bad_cleanup1)
                self.addCleanup(bad_cleanup2)
            def test_foo(self):
                pass
        suite = unittest.TestSuite([Foo('test_foo')])
        suite(result)
        expected_out = '\nStdout:\nset up\ndo cleanup2\ndo cleanup1\n'
        self.assertEqual(stdout.getvalue(), expected_out)
        self.assertEqual(len(result.errors), 2)
        description = f'test_foo ({strclass(Foo)}.test_foo)'
        test_case, formatted_exc = result.errors[0]
        self.assertEqual(str(test_case), description)
        self.assertIn('ValueError: bad cleanup2', formatted_exc)
        self.assertNotIn('TypeError', formatted_exc)
        self.assertIn('\nStdout:\nset up\ndo cleanup2\n', formatted_exc)
        self.assertNotIn('\ndo cleanup1\n', formatted_exc)
        test_case, formatted_exc = result.errors[1]
        self.assertEqual(str(test_case), description)
        self.assertIn('TypeError: bad cleanup1', formatted_exc)
        self.assertNotIn('ValueError', formatted_exc)
        self.assertIn(expected_out, formatted_exc)

    def testBufferSetUp_DoCleanups(self):
        with captured_stdout() as stdout:
            result = unittest.TestResult()
        result.buffer = True

        class Foo(unittest.TestCase):
            def setUp(self):
                print('set up')
                self.addCleanup(bad_cleanup1)
                self.addCleanup(bad_cleanup2)
                1/0
            def test_foo(self):
                pass
        suite = unittest.TestSuite([Foo('test_foo')])
        suite(result)
        expected_out = '\nStdout:\nset up\ndo cleanup2\ndo cleanup1\n'
        self.assertEqual(stdout.getvalue(), expected_out)
        self.assertEqual(len(result.errors), 3)
        description = f'test_foo ({strclass(Foo)}.test_foo)'
        test_case, formatted_exc = result.errors[0]
        self.assertEqual(str(test_case), description)
        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
        self.assertNotIn('ValueError', formatted_exc)
        self.assertNotIn('TypeError', formatted_exc)
        self.assertIn('\nStdout:\nset up\n', formatted_exc)
        self.assertNotIn('\ndo cleanup2\n', formatted_exc)
        self.assertNotIn('\ndo cleanup1\n', formatted_exc)
        test_case, formatted_exc = result.errors[1]
        self.assertEqual(str(test_case), description)
        self.assertIn('ValueError: bad cleanup2', formatted_exc)
        self.assertNotIn('ZeroDivisionError', formatted_exc)
        self.assertNotIn('TypeError', formatted_exc)
        self.assertIn('\nStdout:\nset up\ndo cleanup2\n', formatted_exc)
        self.assertNotIn('\ndo cleanup1\n', formatted_exc)
        test_case, formatted_exc = result.errors[2]
        self.assertEqual(str(test_case), description)
        self.assertIn('TypeError: bad cleanup1', formatted_exc)
        self.assertNotIn('ZeroDivisionError', formatted_exc)
        self.assertNotIn('ValueError', formatted_exc)
        self.assertIn(expected_out, formatted_exc)

    def testBufferTearDown_DoCleanups(self):
        with captured_stdout() as stdout:
            result = unittest.TestResult()
        result.buffer = True

        class Foo(unittest.TestCase):
            def setUp(self):
                print('set up')
                self.addCleanup(bad_cleanup1)
                self.addCleanup(bad_cleanup2)
            def tearDown(self):
                print('tear down')
                1/0
            def test_foo(self):
                pass
        suite = unittest.TestSuite([Foo('test_foo')])
        suite(result)
        expected_out = '\nStdout:\nset up\ntear down\ndo cleanup2\ndo cleanup1\n'
        self.assertEqual(stdout.getvalue(), expected_out)
        self.assertEqual(len(result.errors), 3)
        description = f'test_foo ({strclass(Foo)}.test_foo)'
        test_case, formatted_exc = result.errors[0]
        self.assertEqual(str(test_case), description)
        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
        self.assertNotIn('ValueError', formatted_exc)
        self.assertNotIn('TypeError', formatted_exc)
        self.assertIn('\nStdout:\nset up\ntear down\n', formatted_exc)
        self.assertNotIn('\ndo cleanup2\n', formatted_exc)
        self.assertNotIn('\ndo cleanup1\n', formatted_exc)
        test_case, formatted_exc = result.errors[1]
        self.assertEqual(str(test_case), description)
        self.assertIn('ValueError: bad cleanup2', formatted_exc)
        self.assertNotIn('ZeroDivisionError', formatted_exc)
        self.assertNotIn('TypeError', formatted_exc)
        self.assertIn('\nStdout:\nset up\ntear down\ndo cleanup2\n', formatted_exc)
        self.assertNotIn('\ndo cleanup1\n', formatted_exc)
        test_case, formatted_exc = result.errors[2]
        self.assertEqual(str(test_case), description)
        self.assertIn('TypeError: bad cleanup1', formatted_exc)
        self.assertNotIn('ZeroDivisionError', formatted_exc)
        self.assertNotIn('ValueError', formatted_exc)
        self.assertIn(expected_out, formatted_exc)

    def testBufferSetupClass(self):
        with captured_stdout() as stdout:
            result = unittest.TestResult()
        result.buffer = True

        class Foo(unittest.TestCase):
            @classmethod
            def setUpClass(cls):
                print('set up class')
                1/0
            def test_foo(self):
                pass
        suite = unittest.TestSuite([Foo('test_foo')])
        suite(result)
        expected_out = '\nStdout:\nset up class\n'
        self.assertEqual(stdout.getvalue(), expected_out)
        self.assertEqual(len(result.errors), 1)
        description = f'setUpClass ({strclass(Foo)})'
        test_case, formatted_exc = result.errors[0]
        self.assertEqual(test_case.description, description)
        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
        self.assertIn(expected_out, formatted_exc)

    def testBufferTearDownClass(self):
        with captured_stdout() as stdout:
            result = unittest.TestResult()
        result.buffer = True

        class Foo(unittest.TestCase):
            @classmethod
            def tearDownClass(cls):
                print('tear down class')
                1/0
            def test_foo(self):
                pass
        suite = unittest.TestSuite([Foo('test_foo')])
        suite(result)
        expected_out = '\nStdout:\ntear down class\n'
        self.assertEqual(stdout.getvalue(), expected_out)
        self.assertEqual(len(result.errors), 1)
        description = f'tearDownClass ({strclass(Foo)})'
        test_case, formatted_exc = result.errors[0]
        self.assertEqual(test_case.description, description)
        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
        self.assertIn(expected_out, formatted_exc)

    def testBufferDoClassCleanups(self):
        with captured_stdout() as stdout:
            result = unittest.TestResult()
        result.buffer = True

        class Foo(unittest.TestCase):
            @classmethod
            def setUpClass(cls):
                print('set up class')
                cls.addClassCleanup(bad_cleanup1)
                cls.addClassCleanup(bad_cleanup2)
            @classmethod
            def tearDownClass(cls):
                print('tear down class')
            def test_foo(self):
                pass
        suite = unittest.TestSuite([Foo('test_foo')])
        suite(result)
        expected_out = '\nStdout:\ntear down class\ndo cleanup2\ndo cleanup1\n'
        self.assertEqual(stdout.getvalue(), expected_out)
        self.assertEqual(len(result.errors), 2)
        description = f'tearDownClass ({strclass(Foo)})'
        test_case, formatted_exc = result.errors[0]
        self.assertEqual(test_case.description, description)
        self.assertIn('ValueError: bad cleanup2', formatted_exc)
        self.assertNotIn('TypeError', formatted_exc)
        self.assertIn(expected_out, formatted_exc)
        test_case, formatted_exc = result.errors[1]
        self.assertEqual(test_case.description, description)
        self.assertIn('TypeError: bad cleanup1', formatted_exc)
        self.assertNotIn('ValueError', formatted_exc)
        self.assertIn(expected_out, formatted_exc)

    def testBufferSetupClass_DoClassCleanups(self):
        with captured_stdout() as stdout:
            result = unittest.TestResult()
        result.buffer = True

        class Foo(unittest.TestCase):
            @classmethod
            def setUpClass(cls):
                print('set up class')
                cls.addClassCleanup(bad_cleanup1)
                cls.addClassCleanup(bad_cleanup2)
                1/0
            def test_foo(self):
                pass
        suite = unittest.TestSuite([Foo('test_foo')])
        suite(result)
        expected_out = '\nStdout:\nset up class\ndo cleanup2\ndo cleanup1\n'
        self.assertEqual(stdout.getvalue(), expected_out)
        self.assertEqual(len(result.errors), 3)
        description = f'setUpClass ({strclass(Foo)})'
        test_case, formatted_exc = result.errors[0]
        self.assertEqual(test_case.description, description)
        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
        self.assertNotIn('ValueError', formatted_exc)
        self.assertNotIn('TypeError', formatted_exc)
        self.assertIn('\nStdout:\nset up class\n', formatted_exc)
        test_case, formatted_exc = result.errors[1]
        self.assertEqual(test_case.description, description)
        self.assertIn('ValueError: bad cleanup2', formatted_exc)
        self.assertNotIn('ZeroDivisionError', formatted_exc)
        self.assertNotIn('TypeError', formatted_exc)
        self.assertIn(expected_out, formatted_exc)
        test_case, formatted_exc = result.errors[2]
        self.assertEqual(test_case.description, description)
        self.assertIn('TypeError: bad cleanup1', formatted_exc)
        self.assertNotIn('ZeroDivisionError', formatted_exc)
        self.assertNotIn('ValueError', formatted_exc)
        self.assertIn(expected_out, formatted_exc)

    def testBufferTearDownClass_DoClassCleanups(self):
        with captured_stdout() as stdout:
            result = unittest.TestResult()
        result.buffer = True

        class Foo(unittest.TestCase):
            @classmethod
            def setUpClass(cls):
                print('set up class')
                cls.addClassCleanup(bad_cleanup1)
                cls.addClassCleanup(bad_cleanup2)
            @classmethod
            def tearDownClass(cls):
                print('tear down class')
                1/0
            def test_foo(self):
                pass
        suite = unittest.TestSuite([Foo('test_foo')])
        suite(result)
        expected_out = '\nStdout:\ntear down class\ndo cleanup2\ndo cleanup1\n'
        self.assertEqual(stdout.getvalue(), expected_out)
        self.assertEqual(len(result.errors), 3)
        description = f'tearDownClass ({strclass(Foo)})'
        test_case, formatted_exc = result.errors[0]
        self.assertEqual(test_case.description, description)
        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
        self.assertNotIn('ValueError', formatted_exc)
        self.assertNotIn('TypeError', formatted_exc)
        self.assertIn('\nStdout:\ntear down class\n', formatted_exc)
        test_case, formatted_exc = result.errors[1]
        self.assertEqual(test_case.description, description)
        self.assertIn('ValueError: bad cleanup2', formatted_exc)
        self.assertNotIn('ZeroDivisionError', formatted_exc)
        self.assertNotIn('TypeError', formatted_exc)
        self.assertIn(expected_out, formatted_exc)
        test_case, formatted_exc = result.errors[2]
        self.assertEqual(test_case.description, description)
        self.assertIn('TypeError: bad cleanup1', formatted_exc)
        self.assertNotIn('ZeroDivisionError', formatted_exc)
        self.assertNotIn('ValueError', formatted_exc)
        self.assertIn(expected_out, formatted_exc)

    def testBufferSetUpModule(self):
        with captured_stdout() as stdout:
            result = unittest.TestResult()
        result.buffer = True

        class Foo(unittest.TestCase):
            def test_foo(self):
                pass
        class Module(object):
            @staticmethod
            def setUpModule():
                print('set up module')
                1/0

        Foo.__module__ = 'Module'
        sys.modules['Module'] = Module
        self.addCleanup(sys.modules.pop, 'Module')
        suite = unittest.TestSuite([Foo('test_foo')])
        suite(result)
        expected_out = '\nStdout:\nset up module\n'
        self.assertEqual(stdout.getvalue(), expected_out)
        self.assertEqual(len(result.errors), 1)
        description = 'setUpModule (Module)'
        test_case, formatted_exc = result.errors[0]
        self.assertEqual(test_case.description, description)
        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
        self.assertIn(expected_out, formatted_exc)

    def testBufferTearDownModule(self):
        with captured_stdout() as stdout:
            result = unittest.TestResult()
        result.buffer = True

        class Foo(unittest.TestCase):
            def test_foo(self):
                pass
        class Module(object):
            @staticmethod
            def tearDownModule():
                print('tear down module')
                1/0

        Foo.__module__ = 'Module'
        sys.modules['Module'] = Module
        self.addCleanup(sys.modules.pop, 'Module')
        suite = unittest.TestSuite([Foo('test_foo')])
        suite(result)
        expected_out = '\nStdout:\ntear down module\n'
        self.assertEqual(stdout.getvalue(), expected_out)
        self.assertEqual(len(result.errors), 1)
        description = 'tearDownModule (Module)'
        test_case, formatted_exc = result.errors[0]
        self.assertEqual(test_case.description, description)
        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
        self.assertIn(expected_out, formatted_exc)

    def testBufferDoModuleCleanups(self):
        with captured_stdout() as stdout:
            result = unittest.TestResult()
        result.buffer = True

        class Foo(unittest.TestCase):
            def test_foo(self):
                pass
        class Module(object):
            @staticmethod
            def setUpModule():
                print('set up module')
                unittest.addModuleCleanup(bad_cleanup1)
                unittest.addModuleCleanup(bad_cleanup2)

        Foo.__module__ = 'Module'
        sys.modules['Module'] = Module
        self.addCleanup(sys.modules.pop, 'Module')
        suite = unittest.TestSuite([Foo('test_foo')])
        suite(result)
        expected_out = '\nStdout:\ndo cleanup2\ndo cleanup1\n'
        self.assertEqual(stdout.getvalue(), expected_out)
        self.assertEqual(len(result.errors), 1)
        description = 'tearDownModule (Module)'
        test_case, formatted_exc = result.errors[0]
        self.assertEqual(test_case.description, description)
        self.assertIn('ValueError: bad cleanup2', formatted_exc)
        self.assertNotIn('TypeError', formatted_exc)
        self.assertIn(expected_out, formatted_exc)

    def testBufferSetUpModule_DoModuleCleanups(self):
        with captured_stdout() as stdout:
            result = unittest.TestResult()
        result.buffer = True

        class Foo(unittest.TestCase):
            def test_foo(self):
                pass
        class Module(object):
            @staticmethod
            def setUpModule():
                print('set up module')
                unittest.addModuleCleanup(bad_cleanup1)
                unittest.addModuleCleanup(bad_cleanup2)
                1/0

        Foo.__module__ = 'Module'
        sys.modules['Module'] = Module
        self.addCleanup(sys.modules.pop, 'Module')
        suite = unittest.TestSuite([Foo('test_foo')])
        suite(result)
        expected_out = '\nStdout:\nset up module\ndo cleanup2\ndo cleanup1\n'
        self.assertEqual(stdout.getvalue(), expected_out)
        self.assertEqual(len(result.errors), 2)
        description = 'setUpModule (Module)'
        test_case, formatted_exc = result.errors[0]
        self.assertEqual(test_case.description, description)
        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
        self.assertNotIn('ValueError', formatted_exc)
        self.assertNotIn('TypeError', formatted_exc)
        self.assertIn('\nStdout:\nset up module\n', formatted_exc)
        test_case, formatted_exc = result.errors[1]
        self.assertIn(expected_out, formatted_exc)
        self.assertEqual(test_case.description, description)
        self.assertIn('ValueError: bad cleanup2', formatted_exc)
        self.assertNotIn('ZeroDivisionError', formatted_exc)
        self.assertNotIn('TypeError', formatted_exc)
        self.assertIn(expected_out, formatted_exc)

    def testBufferTearDownModule_DoModuleCleanups(self):
        with captured_stdout() as stdout:
            result = unittest.TestResult()
        result.buffer = True

        class Foo(unittest.TestCase):
            def test_foo(self):
                pass
        class Module(object):
            @staticmethod
            def setUpModule():
                print('set up module')
                unittest.addModuleCleanup(bad_cleanup1)
                unittest.addModuleCleanup(bad_cleanup2)
            @staticmethod
            def tearDownModule():
                print('tear down module')
                1/0

        Foo.__module__ = 'Module'
        sys.modules['Module'] = Module
        self.addCleanup(sys.modules.pop, 'Module')
        suite = unittest.TestSuite([Foo('test_foo')])
        suite(result)
        expected_out = '\nStdout:\ntear down module\ndo cleanup2\ndo cleanup1\n'
        self.assertEqual(stdout.getvalue(), expected_out)
        self.assertEqual(len(result.errors), 2)
        description = 'tearDownModule (Module)'
        test_case, formatted_exc = result.errors[0]
        self.assertEqual(test_case.description, description)
        self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
        self.assertNotIn('ValueError', formatted_exc)
        self.assertNotIn('TypeError', formatted_exc)
        self.assertIn('\nStdout:\ntear down module\n', formatted_exc)
        test_case, formatted_exc = result.errors[1]
        self.assertEqual(test_case.description, description)
        self.assertIn('ValueError: bad cleanup2', formatted_exc)
        self.assertNotIn('ZeroDivisionError', formatted_exc)
        self.assertNotIn('TypeError', formatted_exc)
        self.assertIn(expected_out, formatted_exc)


if __name__ == '__main__':
    unittest.main()