~jfb-tempo-consulting/unifield-wm/sync-env-py3

« back to all changes in this revision

Viewing changes to unittest27/result.py

  • Committer: Samus CTO
  • Date: 2012-08-28 12:38:31 UTC
  • Revision ID: cto@openerp.com-20120828123831-9dhavvjktnrl2p8d
[INIT]

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
"""Test result object"""
2
 
 
3
 
import os
4
 
import sys
5
 
import traceback
6
 
 
7
 
from io import StringIO
8
 
 
9
 
from . import util
10
 
from functools import wraps
11
 
 
12
 
__unittest = True
13
 
 
14
 
def 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
 
 
22
 
STDOUT_LINE = '\nStdout:\n%s'
23
 
STDERR_LINE = '\nStderr:\n%s'
24
 
 
25
 
 
26
 
class 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)))