9 class _WritelnDecorator(object):
10 """Used to decorate file-like objects with a handy 'writeln' method"""
11 def __init__(self
,stream
):
14 def __getattr__(self
, attr
):
15 return getattr(self
.stream
,attr
)
17 def writeln(self
, arg
=None):
20 self
.write('\n') # text-mode streams translate to \r\n if needed
23 class _TextTestResult(result
.TestResult
):
24 """A test result class that can print formatted text results to a stream.
26 Used by TextTestRunner.
31 def __init__(self
, stream
, descriptions
, verbosity
):
32 super(_TextTestResult
, self
).__init
__()
34 self
.showAll
= verbosity
> 1
35 self
.dots
= verbosity
== 1
36 self
.descriptions
= descriptions
38 def getDescription(self
, test
):
40 return test
.shortDescription() or str(test
)
44 def startTest(self
, test
):
45 super(_TextTestResult
, self
).startTest(test
)
47 self
.stream
.write(self
.getDescription(test
))
48 self
.stream
.write(" ... ")
51 def addSuccess(self
, test
):
52 super(_TextTestResult
, self
).addSuccess(test
)
54 self
.stream
.writeln("ok")
56 self
.stream
.write('.')
59 def addError(self
, test
, err
):
60 super(_TextTestResult
, self
).addError(test
, err
)
62 self
.stream
.writeln("ERROR")
64 self
.stream
.write('E')
67 def addFailure(self
, test
, err
):
68 super(_TextTestResult
, self
).addFailure(test
, err
)
70 self
.stream
.writeln("FAIL")
72 self
.stream
.write('F')
75 def addSkip(self
, test
, reason
):
76 super(_TextTestResult
, self
).addSkip(test
, reason
)
78 self
.stream
.writeln("skipped {0!r}".format(reason
))
80 self
.stream
.write("s")
83 def addExpectedFailure(self
, test
, err
):
84 super(_TextTestResult
, self
).addExpectedFailure(test
, err
)
86 self
.stream
.writeln("expected failure")
88 self
.stream
.write("x")
91 def addUnexpectedSuccess(self
, test
):
92 super(_TextTestResult
, self
).addUnexpectedSuccess(test
)
94 self
.stream
.writeln("unexpected success")
96 self
.stream
.write("u")
99 def printErrors(self
):
100 if self
.dots
or self
.showAll
:
101 self
.stream
.writeln()
102 self
.printErrorList('ERROR', self
.errors
)
103 self
.printErrorList('FAIL', self
.failures
)
105 def printErrorList(self
, flavour
, errors
):
106 for test
, err
in errors
:
107 self
.stream
.writeln(self
.separator1
)
108 self
.stream
.writeln("%s: %s" % (flavour
,self
.getDescription(test
)))
109 self
.stream
.writeln(self
.separator2
)
110 self
.stream
.writeln("%s" % err
)
113 class TextTestRunner(object):
114 """A test runner class that displays results in textual form.
116 It prints out the names of tests as they are run, errors as they
117 occur, and a summary of the results at the end of the test run.
119 def __init__(self
, stream
=sys
.stderr
, descriptions
=1, verbosity
=1):
120 self
.stream
= _WritelnDecorator(stream
)
121 self
.descriptions
= descriptions
122 self
.verbosity
= verbosity
124 def _makeResult(self
):
125 return _TextTestResult(self
.stream
, self
.descriptions
, self
.verbosity
)
128 "Run the given test case or test suite."
129 result
= self
._makeResult
()
130 startTime
= time
.time()
131 startTestRun
= getattr(result
, 'startTestRun', None)
132 if startTestRun
is not None:
137 stopTestRun
= getattr(result
, 'stopTestRun', None)
138 if stopTestRun
is not None:
140 stopTime
= time
.time()
141 timeTaken
= stopTime
- startTime
143 self
.stream
.writeln(result
.separator2
)
144 run
= result
.testsRun
145 self
.stream
.writeln("Ran %d test%s in %.3fs" %
146 (run
, run
!= 1 and "s" or "", timeTaken
))
147 self
.stream
.writeln()
148 results
= map(len, (result
.expectedFailures
,
149 result
.unexpectedSuccesses
,
151 expectedFails
, unexpectedSuccesses
, skipped
= results
153 if not result
.wasSuccessful():
154 self
.stream
.write("FAILED")
155 failed
, errored
= map(len, (result
.failures
, result
.errors
))
157 infos
.append("failures=%d" % failed
)
159 infos
.append("errors=%d" % errored
)
161 self
.stream
.write("OK")
163 infos
.append("skipped=%d" % skipped
)
165 infos
.append("expected failures=%d" % expectedFails
)
166 if unexpectedSuccesses
:
167 infos
.append("unexpected successes=%d" % unexpectedSuccesses
)
169 self
.stream
.writeln(" (%s)" % (", ".join(infos
),))
171 self
.stream
.write("\n")