8 from unittest2 import result
11 from unittest2.signals import registerResult
13 def registerResult(_):
19 class _WritelnDecorator(object):
20 """Used to decorate file-like objects with a handy 'writeln' method"""
22 def __init__(self, stream):
25 def __getattr__(self, attr):
26 if attr in ('stream', '__getstate__'):
27 raise AttributeError(attr)
28 return getattr(self.stream, attr)
30 def writeln(self, arg=None):
33 self.write('\n') # text-mode streams translate to \r\n if needed
36 class TextTestResult(result.TestResult):
37 """A test result class that can print formatted text results to a stream.
39 Used by TextTestRunner.
44 def __init__(self, stream, descriptions, verbosity):
45 super(TextTestResult, self).__init__()
47 self.showAll = verbosity > 1
48 self.dots = verbosity == 1
49 self.descriptions = descriptions
50 self.progressbar = None
54 ".=success F=fail E=error s=skipped x=expected-fail u=unexpected-success")
55 self.stream.writeln("")
58 def getDescription(self, test):
59 doc_first_line = test.shortDescription()
60 if self.descriptions and doc_first_line:
61 return '\n'.join((str(test), doc_first_line))
65 def startTest(self, test):
66 super(TextTestResult, self).startTest(test)
68 self.stream.write(self.getDescription(test))
69 self.stream.write(" ... ")
72 def newTestResult(self, test, result_short, result_long):
74 self.stream.writeln(result_long)
75 elif self.progressbar:
76 self.progressbar.__add__(1)
77 self.progressbar.add_event(result_short)
78 self.progressbar.show_progress()
80 self.stream.write(result_short)
83 def addSuccess(self, test):
84 super(TextTestResult, self).addSuccess(test)
86 self.newTestResult(test, "ok", "ok")
88 self.newTestResult(test, ".", "ok")
90 def addError(self, test, err):
91 super(TextTestResult, self).addError(test, err)
92 self.newTestResult(test, "E", "ERROR")
94 def addFailure(self, test, err):
95 super(TextTestResult, self).addFailure(test, err)
96 self.newTestResult(test, "F", "FAILURE")
98 def addSkip(self, test, reason):
99 super(TextTestResult, self).addSkip(test, reason)
100 self.newTestResult(test, "s", "skipped %r" % (reason,))
102 def addExpectedFailure(self, test, err, bugnumber):
103 super(TextTestResult, self).addExpectedFailure(test, err, bugnumber)
104 self.newTestResult(test, "x", "expected failure")
106 def addUnexpectedSuccess(self, test, bugnumber):
107 super(TextTestResult, self).addUnexpectedSuccess(test, bugnumber)
108 self.newTestResult(test, "u", "unexpected success")
110 def printErrors(self):
112 self.progressbar.complete()
113 self.progressbar.show_progress()
114 if self.dots or self.showAll:
115 self.stream.writeln()
116 self.printErrorList('ERROR', self.errors)
117 self.printErrorList('FAIL', self.failures)
119 def printErrorList(self, flavour, errors):
120 for test, err in errors:
121 self.stream.writeln(self.separator1)
122 self.stream.writeln("%s: %s" %
123 (flavour, self.getDescription(test)))
124 self.stream.writeln(self.separator2)
125 self.stream.writeln("%s" % err)
127 def stopTestRun(self):
128 super(TextTestResult, self).stopTestRun()
132 class TextTestRunner(unittest.TextTestRunner):
133 """A test runner class that displays results in textual form.
135 It prints out the names of tests as they are run, errors as they
136 occur, and a summary of the results at the end of the test run.
138 resultclass = TextTestResult
140 def __init__(self, stream=sys.stderr, descriptions=True, verbosity=1,
141 failfast=False, buffer=False, resultclass=None):
142 self.stream = _WritelnDecorator(stream)
143 self.descriptions = descriptions
144 self.verbosity = verbosity
145 self.failfast = failfast
147 if resultclass is not None:
148 self.resultclass = resultclass
150 def _makeResult(self):
151 return self.resultclass(self.stream, self.descriptions, self.verbosity)
154 "Run the given test case or test suite."
155 result = self._makeResult()
156 result.failfast = self.failfast
157 result.buffer = self.buffer
158 registerResult(result)
160 startTime = time.time()
161 startTestRun = getattr(result, 'startTestRun', None)
162 if startTestRun is not None:
167 stopTestRun = getattr(result, 'stopTestRun', None)
168 if stopTestRun is not None:
172 stopTime = time.time()
173 timeTaken = stopTime - startTime
174 if hasattr(result, 'separator2'):
175 self.stream.writeln(result.separator2)
176 run = result.testsRun
177 self.stream.writeln("Ran %d test%s in %.3fs" %
178 (run, run != 1 and "s" or "", timeTaken))
179 self.stream.writeln()
181 expectedFails = unexpectedSuccesses = skipped = passed = failed = errored = 0
183 results = map(len, (result.expectedFailures,
184 result.unexpectedSuccesses,
189 expectedFails, unexpectedSuccesses, skipped, passed, failed, errored = results
190 except AttributeError:
193 infos.append("%d passes" % passed)
194 infos.append("%d failures" % failed)
195 infos.append("%d errors" % errored)
196 infos.append("%d skipped" % skipped)
197 infos.append("%d expected failures" % expectedFails)
198 infos.append("%d unexpected successes" % unexpectedSuccesses)
199 self.stream.write("RESULT: ")
200 if not result.wasSuccessful():
201 self.stream.write("FAILED")
203 self.stream.write("PASSED")
205 self.stream.writeln(" (%s)" % (", ".join(infos),))