PageRenderTime 26ms CodeModel.GetById 15ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/lib-python/2.7/unittest/result.py

http://github.com/pypy/pypy
Python | 193 lines | 156 code | 17 blank | 20 comment | 11 complexity | c7ea1955d5803f5f564228a444df899c MD5 | raw file
  1"""Test result object"""
  2
  3import os
  4import sys
  5import traceback
  6
  7from StringIO import StringIO
  8
  9from . import util
 10from functools import wraps
 11
 12__unittest = True
 13
 14def failfast(method):
 15    @wraps(method)
 16    def inner(self, *args, **kw):
 17        if getattr(self, 'failfast', False):
 18            self.stop()
 19        return method(self, *args, **kw)
 20    return inner
 21
 22STDOUT_LINE = '\nStdout:\n%s'
 23STDERR_LINE = '\nStderr:\n%s'
 24
 25
 26class TestResult(object):
 27    """Holder for test result information.
 28
 29    Test results are automatically managed by the TestCase and TestSuite
 30    classes, and do not need to be explicitly manipulated by writers of tests.
 31
 32    Each instance holds the total number of tests run, and collections of
 33    failures and errors that occurred among those test runs. The collections
 34    contain tuples of (testcase, exceptioninfo), where exceptioninfo is the
 35    formatted traceback of the error that occurred.
 36    """
 37    _previousTestClass = None
 38    _testRunEntered = False
 39    _moduleSetUpFailed = False
 40    def __init__(self, stream=None, descriptions=None, verbosity=None):
 41        self.failfast = False
 42        self.failures = []
 43        self.errors = []
 44        self.testsRun = 0
 45        self.skipped = []
 46        self.expectedFailures = []
 47        self.unexpectedSuccesses = []
 48        self.shouldStop = False
 49        self.buffer = False
 50        self._stdout_buffer = None
 51        self._stderr_buffer = None
 52        self._original_stdout = sys.stdout
 53        self._original_stderr = sys.stderr
 54        self._mirrorOutput = False
 55
 56    def printErrors(self):
 57        "Called by TestRunner after test run"
 58
 59    def startTest(self, test):
 60        "Called when the given test is about to be run"
 61        self.testsRun += 1
 62        self._mirrorOutput = False
 63        self._setupStdout()
 64
 65    def _setupStdout(self):
 66        if self.buffer:
 67            if self._stderr_buffer is None:
 68                self._stderr_buffer = StringIO()
 69                self._stdout_buffer = StringIO()
 70            sys.stdout = self._stdout_buffer
 71            sys.stderr = self._stderr_buffer
 72
 73    def startTestRun(self):
 74        """Called once before any tests are executed.
 75
 76        See startTest for a method called before each test.
 77        """
 78
 79    def stopTest(self, test):
 80        """Called when the given test has been run"""
 81        self._restoreStdout()
 82        self._mirrorOutput = False
 83
 84    def _restoreStdout(self):
 85        if self.buffer:
 86            if self._mirrorOutput:
 87                output = sys.stdout.getvalue()
 88                error = sys.stderr.getvalue()
 89                if output:
 90                    if not output.endswith('\n'):
 91                        output += '\n'
 92                    self._original_stdout.write(STDOUT_LINE % output)
 93                if error:
 94                    if not error.endswith('\n'):
 95                        error += '\n'
 96                    self._original_stderr.write(STDERR_LINE % error)
 97
 98            sys.stdout = self._original_stdout
 99            sys.stderr = self._original_stderr
100            self._stdout_buffer.seek(0)
101            self._stdout_buffer.truncate()
102            self._stderr_buffer.seek(0)
103            self._stderr_buffer.truncate()
104
105    def stopTestRun(self):
106        """Called once after all tests are executed.
107
108        See stopTest for a method called after each test.
109        """
110
111    @failfast
112    def addError(self, test, err):
113        """Called when an error has occurred. 'err' is a tuple of values as
114        returned by sys.exc_info().
115        """
116        self.errors.append((test, self._exc_info_to_string(err, test)))
117        self._mirrorOutput = True
118
119    @failfast
120    def addFailure(self, test, err):
121        """Called when an error has occurred. 'err' is a tuple of values as
122        returned by sys.exc_info()."""
123        self.failures.append((test, self._exc_info_to_string(err, test)))
124        self._mirrorOutput = True
125
126    def addSuccess(self, test):
127        "Called when a test has completed successfully"
128        pass
129
130    def addSkip(self, test, reason):
131        """Called when a test is skipped."""
132        self.skipped.append((test, reason))
133
134    def addExpectedFailure(self, test, err):
135        """Called when an expected failure/error occured."""
136        self.expectedFailures.append(
137            (test, self._exc_info_to_string(err, test)))
138
139    @failfast
140    def addUnexpectedSuccess(self, test):
141        """Called when a test was expected to fail, but succeed."""
142        self.unexpectedSuccesses.append(test)
143
144    def wasSuccessful(self):
145        "Tells whether or not this result was a success"
146        return len(self.failures) == len(self.errors) == 0
147
148    def stop(self):
149        "Indicates that the tests should be aborted"
150        self.shouldStop = True
151
152    def _exc_info_to_string(self, err, test):
153        """Converts a sys.exc_info()-style tuple of values into a string."""
154        exctype, value, tb = err
155        # Skip test runner traceback levels
156        while tb and self._is_relevant_tb_level(tb):
157            tb = tb.tb_next
158
159        if exctype is test.failureException:
160            # Skip assert*() traceback levels
161            length = self._count_relevant_tb_levels(tb)
162            msgLines = traceback.format_exception(exctype, value, tb, length)
163        else:
164            msgLines = traceback.format_exception(exctype, value, tb)
165
166        if self.buffer:
167            output = sys.stdout.getvalue()
168            error = sys.stderr.getvalue()
169            if output:
170                if not output.endswith('\n'):
171                    output += '\n'
172                msgLines.append(STDOUT_LINE % output)
173            if error:
174                if not error.endswith('\n'):
175                    error += '\n'
176                msgLines.append(STDERR_LINE % error)
177        return ''.join(msgLines)
178
179
180    def _is_relevant_tb_level(self, tb):
181        return '__unittest' in tb.tb_frame.f_globals
182
183    def _count_relevant_tb_levels(self, tb):
184        length = 0
185        while tb and not self._is_relevant_tb_level(tb):
186            length += 1
187            tb = tb.tb_next
188        return length
189
190    def __repr__(self):
191        return ("<%s run=%i errors=%i failures=%i>" %
192               (util.strclass(self.__class__), self.testsRun, len(self.errors),
193                len(self.failures)))