diff options
author | Benjamin Peterson <benjamin@python.org> | 2009-07-19 21:01:52 (GMT) |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2009-07-19 21:01:52 (GMT) |
commit | bed7d04fedd800a8d3bd8a7c9c3ff823e365c236 (patch) | |
tree | f7e20f085f4c4a6a4cc0227ab16aa73d1dd7dc8e /Lib/unittest/runner.py | |
parent | c4296d1edc1f05f96cc7b6b3e1c3df9dd596d5f4 (diff) | |
download | cpython-bed7d04fedd800a8d3bd8a7c9c3ff823e365c236.zip cpython-bed7d04fedd800a8d3bd8a7c9c3ff823e365c236.tar.gz cpython-bed7d04fedd800a8d3bd8a7c9c3ff823e365c236.tar.bz2 |
Merged revisions 74095 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r74095 | benjamin.peterson | 2009-07-19 15:18:21 -0500 (Sun, 19 Jul 2009) | 1 line
split unittest.py into a package
........
Diffstat (limited to 'Lib/unittest/runner.py')
-rw-r--r-- | Lib/unittest/runner.py | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/Lib/unittest/runner.py b/Lib/unittest/runner.py new file mode 100644 index 0000000..ea3c585 --- /dev/null +++ b/Lib/unittest/runner.py @@ -0,0 +1,172 @@ +"""Running tests""" + +import sys +import time + +from . import result + + +class _WritelnDecorator(object): + """Used to decorate file-like objects with a handy 'writeln' method""" + def __init__(self,stream): + self.stream = stream + + def __getattr__(self, attr): + return getattr(self.stream,attr) + + def writeln(self, arg=None): + if arg: + self.write(arg) + self.write('\n') # text-mode streams translate to \r\n if needed + + +class _TextTestResult(result.TestResult): + """A test result class that can print formatted text results to a stream. + + Used by TextTestRunner. + """ + separator1 = '=' * 70 + separator2 = '-' * 70 + + def __init__(self, stream, descriptions, verbosity): + super(_TextTestResult, self).__init__() + self.stream = stream + self.showAll = verbosity > 1 + self.dots = verbosity == 1 + self.descriptions = descriptions + + def getDescription(self, test): + if self.descriptions: + return test.shortDescription() or str(test) + else: + return str(test) + + def startTest(self, test): + super(_TextTestResult, self).startTest(test) + if self.showAll: + self.stream.write(self.getDescription(test)) + self.stream.write(" ... ") + self.stream.flush() + + def addSuccess(self, test): + super(_TextTestResult, self).addSuccess(test) + if self.showAll: + self.stream.writeln("ok") + elif self.dots: + self.stream.write('.') + self.stream.flush() + + def addError(self, test, err): + super(_TextTestResult, self).addError(test, err) + if self.showAll: + self.stream.writeln("ERROR") + elif self.dots: + self.stream.write('E') + self.stream.flush() + + def addFailure(self, test, err): + super(_TextTestResult, self).addFailure(test, err) + if self.showAll: + self.stream.writeln("FAIL") + elif self.dots: + self.stream.write('F') + self.stream.flush() + + def addSkip(self, test, reason): + super(_TextTestResult, self).addSkip(test, reason) + if self.showAll: + self.stream.writeln("skipped {0!r}".format(reason)) + elif self.dots: + self.stream.write("s") + self.stream.flush() + + def addExpectedFailure(self, test, err): + super(_TextTestResult, self).addExpectedFailure(test, err) + if self.showAll: + self.stream.writeln("expected failure") + elif self.dots: + self.stream.write("x") + self.stream.flush() + + def addUnexpectedSuccess(self, test): + super(_TextTestResult, self).addUnexpectedSuccess(test) + if self.showAll: + self.stream.writeln("unexpected success") + elif self.dots: + self.stream.write("u") + self.stream.flush() + + def printErrors(self): + if self.dots or self.showAll: + self.stream.writeln() + self.printErrorList('ERROR', self.errors) + self.printErrorList('FAIL', self.failures) + + def printErrorList(self, flavour, errors): + for test, err in errors: + self.stream.writeln(self.separator1) + self.stream.writeln("%s: %s" % (flavour,self.getDescription(test))) + self.stream.writeln(self.separator2) + self.stream.writeln("%s" % err) + + +class TextTestRunner(object): + """A test runner class that displays results in textual form. + + It prints out the names of tests as they are run, errors as they + occur, and a summary of the results at the end of the test run. + """ + def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1): + self.stream = _WritelnDecorator(stream) + self.descriptions = descriptions + self.verbosity = verbosity + + def _makeResult(self): + return _TextTestResult(self.stream, self.descriptions, self.verbosity) + + def run(self, test): + "Run the given test case or test suite." + result = self._makeResult() + startTime = time.time() + startTestRun = getattr(result, 'startTestRun', None) + if startTestRun is not None: + startTestRun() + try: + test(result) + finally: + stopTestRun = getattr(result, 'stopTestRun', None) + if stopTestRun is not None: + stopTestRun() + stopTime = time.time() + timeTaken = stopTime - startTime + result.printErrors() + self.stream.writeln(result.separator2) + run = result.testsRun + self.stream.writeln("Ran %d test%s in %.3fs" % + (run, run != 1 and "s" or "", timeTaken)) + self.stream.writeln() + results = map(len, (result.expectedFailures, + result.unexpectedSuccesses, + result.skipped)) + expectedFails, unexpectedSuccesses, skipped = results + infos = [] + if not result.wasSuccessful(): + self.stream.write("FAILED") + failed, errored = len(result.failures), len(result.errors) + if failed: + infos.append("failures=%d" % failed) + if errored: + infos.append("errors=%d" % errored) + else: + self.stream.write("OK") + if skipped: + infos.append("skipped=%d" % skipped) + if expectedFails: + infos.append("expected failures=%d" % expectedFails) + if unexpectedSuccesses: + infos.append("unexpected successes=%d" % unexpectedSuccesses) + if infos: + self.stream.writeln(" (%s)" % (", ".join(infos),)) + else: + self.stream.write("\n") + return result |