comparison CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/lib/python3.8/unittest/result.py @ 69:33d812a61356

planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author jpayne
date Tue, 18 Mar 2025 17:55:14 -0400
parents
children
comparison
equal deleted inserted replaced
67:0e9998148a16 69:33d812a61356
1 """Test result object"""
2
3 import io
4 import sys
5 import traceback
6
7 from . import util
8 from functools import wraps
9
10 __unittest = True
11
12 def failfast(method):
13 @wraps(method)
14 def inner(self, *args, **kw):
15 if getattr(self, 'failfast', False):
16 self.stop()
17 return method(self, *args, **kw)
18 return inner
19
20 STDOUT_LINE = '\nStdout:\n%s'
21 STDERR_LINE = '\nStderr:\n%s'
22
23
24 class TestResult(object):
25 """Holder for test result information.
26
27 Test results are automatically managed by the TestCase and TestSuite
28 classes, and do not need to be explicitly manipulated by writers of tests.
29
30 Each instance holds the total number of tests run, and collections of
31 failures and errors that occurred among those test runs. The collections
32 contain tuples of (testcase, exceptioninfo), where exceptioninfo is the
33 formatted traceback of the error that occurred.
34 """
35 _previousTestClass = None
36 _testRunEntered = False
37 _moduleSetUpFailed = False
38 def __init__(self, stream=None, descriptions=None, verbosity=None):
39 self.failfast = False
40 self.failures = []
41 self.errors = []
42 self.testsRun = 0
43 self.skipped = []
44 self.expectedFailures = []
45 self.unexpectedSuccesses = []
46 self.shouldStop = False
47 self.buffer = False
48 self.tb_locals = False
49 self._stdout_buffer = None
50 self._stderr_buffer = None
51 self._original_stdout = sys.stdout
52 self._original_stderr = sys.stderr
53 self._mirrorOutput = False
54
55 def printErrors(self):
56 "Called by TestRunner after test run"
57
58 def startTest(self, test):
59 "Called when the given test is about to be run"
60 self.testsRun += 1
61 self._mirrorOutput = False
62 self._setupStdout()
63
64 def _setupStdout(self):
65 if self.buffer:
66 if self._stderr_buffer is None:
67 self._stderr_buffer = io.StringIO()
68 self._stdout_buffer = io.StringIO()
69 sys.stdout = self._stdout_buffer
70 sys.stderr = self._stderr_buffer
71
72 def startTestRun(self):
73 """Called once before any tests are executed.
74
75 See startTest for a method called before each test.
76 """
77
78 def stopTest(self, test):
79 """Called when the given test has been run"""
80 self._restoreStdout()
81 self._mirrorOutput = False
82
83 def _restoreStdout(self):
84 if self.buffer:
85 if self._mirrorOutput:
86 output = sys.stdout.getvalue()
87 error = sys.stderr.getvalue()
88 if output:
89 if not output.endswith('\n'):
90 output += '\n'
91 self._original_stdout.write(STDOUT_LINE % output)
92 if error:
93 if not error.endswith('\n'):
94 error += '\n'
95 self._original_stderr.write(STDERR_LINE % error)
96
97 sys.stdout = self._original_stdout
98 sys.stderr = self._original_stderr
99 self._stdout_buffer.seek(0)
100 self._stdout_buffer.truncate()
101 self._stderr_buffer.seek(0)
102 self._stderr_buffer.truncate()
103
104 def stopTestRun(self):
105 """Called once after all tests are executed.
106
107 See stopTest for a method called after each test.
108 """
109
110 @failfast
111 def addError(self, test, err):
112 """Called when an error has occurred. 'err' is a tuple of values as
113 returned by sys.exc_info().
114 """
115 self.errors.append((test, self._exc_info_to_string(err, test)))
116 self._mirrorOutput = True
117
118 @failfast
119 def addFailure(self, test, err):
120 """Called when an error has occurred. 'err' is a tuple of values as
121 returned by sys.exc_info()."""
122 self.failures.append((test, self._exc_info_to_string(err, test)))
123 self._mirrorOutput = True
124
125 def addSubTest(self, test, subtest, err):
126 """Called at the end of a subtest.
127 'err' is None if the subtest ended successfully, otherwise it's a
128 tuple of values as returned by sys.exc_info().
129 """
130 # By default, we don't do anything with successful subtests, but
131 # more sophisticated test results might want to record them.
132 if err is not None:
133 if getattr(self, 'failfast', False):
134 self.stop()
135 if issubclass(err[0], test.failureException):
136 errors = self.failures
137 else:
138 errors = self.errors
139 errors.append((subtest, self._exc_info_to_string(err, test)))
140 self._mirrorOutput = True
141
142 def addSuccess(self, test):
143 "Called when a test has completed successfully"
144 pass
145
146 def addSkip(self, test, reason):
147 """Called when a test is skipped."""
148 self.skipped.append((test, reason))
149
150 def addExpectedFailure(self, test, err):
151 """Called when an expected failure/error occurred."""
152 self.expectedFailures.append(
153 (test, self._exc_info_to_string(err, test)))
154
155 @failfast
156 def addUnexpectedSuccess(self, test):
157 """Called when a test was expected to fail, but succeed."""
158 self.unexpectedSuccesses.append(test)
159
160 def wasSuccessful(self):
161 """Tells whether or not this result was a success."""
162 # The hasattr check is for test_result's OldResult test. That
163 # way this method works on objects that lack the attribute.
164 # (where would such result intances come from? old stored pickles?)
165 return ((len(self.failures) == len(self.errors) == 0) and
166 (not hasattr(self, 'unexpectedSuccesses') or
167 len(self.unexpectedSuccesses) == 0))
168
169 def stop(self):
170 """Indicates that the tests should be aborted."""
171 self.shouldStop = True
172
173 def _exc_info_to_string(self, err, test):
174 """Converts a sys.exc_info()-style tuple of values into a string."""
175 exctype, value, tb = err
176 # Skip test runner traceback levels
177 while tb and self._is_relevant_tb_level(tb):
178 tb = tb.tb_next
179
180 if exctype is test.failureException:
181 # Skip assert*() traceback levels
182 length = self._count_relevant_tb_levels(tb)
183 else:
184 length = None
185 tb_e = traceback.TracebackException(
186 exctype, value, tb, limit=length, capture_locals=self.tb_locals)
187 msgLines = list(tb_e.format())
188
189 if self.buffer:
190 output = sys.stdout.getvalue()
191 error = sys.stderr.getvalue()
192 if output:
193 if not output.endswith('\n'):
194 output += '\n'
195 msgLines.append(STDOUT_LINE % output)
196 if error:
197 if not error.endswith('\n'):
198 error += '\n'
199 msgLines.append(STDERR_LINE % error)
200 return ''.join(msgLines)
201
202
203 def _is_relevant_tb_level(self, tb):
204 return '__unittest' in tb.tb_frame.f_globals
205
206 def _count_relevant_tb_levels(self, tb):
207 length = 0
208 while tb and not self._is_relevant_tb_level(tb):
209 length += 1
210 tb = tb.tb_next
211 return length
212
213 def __repr__(self):
214 return ("<%s run=%i errors=%i failures=%i>" %
215 (util.strclass(self.__class__), self.testsRun, len(self.errors),
216 len(self.failures)))