diff options
| author | Jonathan Lange <jml@mumak.net> | 2012-03-27 13:29:42 +0100 |
|---|---|---|
| committer | Jonathan Lange <jml@mumak.net> | 2012-03-27 13:29:42 +0100 |
| commit | eff5dc6d9da686ebbb2de9444c5bdc46e5a0539f (patch) | |
| tree | f3d317762975775ccdd2a71788a0e8c011661156 /python/subunit/test_results.py | |
| parent | 4786a5fff6f481356f09b7b93b9361678075e489 (diff) | |
| parent | e2cbb8d7bd2fb382ee710a489686fe27ab6cddf2 (diff) | |
| download | subunit-git-eff5dc6d9da686ebbb2de9444c5bdc46e5a0539f.tar.gz | |
Merge lp:~jml/subunit/to-csv -- Add subunit2csv script to filter subunit output
Diffstat (limited to 'python/subunit/test_results.py')
| -rw-r--r-- | python/subunit/test_results.py | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/python/subunit/test_results.py b/python/subunit/test_results.py index 33fb50e..fb7affd 100644 --- a/python/subunit/test_results.py +++ b/python/subunit/test_results.py @@ -16,9 +16,14 @@ """TestResult helper classes used to by subunit.""" +import csv import datetime import testtools +from testtools.content import ( + text_content, + TracebackContent, + ) from subunit import iso8601 @@ -493,3 +498,96 @@ class TestIdPrintingResult(testtools.TestResult): def wasSuccessful(self): "Tells whether or not this result was a success" return self.failed_tests == 0 + + +class TestByTestResult(testtools.TestResult): + """Call something every time a test completes.""" + + # XXX: Arguably belongs in testtools. + + def __init__(self, on_test): + """Construct a ``TestByTestResult``. + + :param on_test: A callable that take a test case, a status (one of + "success", "failure", "error", "skip", or "xfail"), a start time + (a ``datetime`` with timezone), a stop time, an iterable of tags, + and a details dict. Is called at the end of each test (i.e. on + ``stopTest``) with the accumulated values for that test. + """ + super(TestByTestResult, self).__init__() + self._on_test = on_test + + def startTest(self, test): + super(TestByTestResult, self).startTest(test) + self._start_time = self._now() + # There's no supported (i.e. tested) behaviour that relies on these + # being set, but it makes me more comfortable all the same. -- jml + self._status = None + self._details = None + self._stop_time = None + + def stopTest(self, test): + self._stop_time = self._now() + super(TestByTestResult, self).stopTest(test) + self._on_test( + test=test, + status=self._status, + start_time=self._start_time, + stop_time=self._stop_time, + # current_tags is new in testtools 0.9.13. + tags=getattr(self, 'current_tags', None), + details=self._details) + + def _err_to_details(self, test, err, details): + if details: + return details + return {'traceback': TracebackContent(err, test)} + + def addSuccess(self, test, details=None): + super(TestByTestResult, self).addSuccess(test) + self._status = 'success' + self._details = details + + def addFailure(self, test, err=None, details=None): + super(TestByTestResult, self).addFailure(test, err, details) + self._status = 'failure' + self._details = self._err_to_details(test, err, details) + + def addError(self, test, err=None, details=None): + super(TestByTestResult, self).addError(test, err, details) + self._status = 'error' + self._details = self._err_to_details(test, err, details) + + def addSkip(self, test, reason=None, details=None): + super(TestByTestResult, self).addSkip(test, reason, details) + self._status = 'skip' + if details is None: + details = {'reason': text_content(reason)} + elif reason: + # XXX: What if details already has 'reason' key? + details['reason'] = text_content(reason) + self._details = details + + def addExpectedFailure(self, test, err=None, details=None): + super(TestByTestResult, self).addExpectedFailure(test, err, details) + self._status = 'xfail' + self._details = self._err_to_details(test, err, details) + + def addUnexpectedSuccess(self, test, details=None): + super(TestByTestResult, self).addUnexpectedSuccess(test, details) + self._status = 'success' + self._details = details + + +class CsvResult(TestByTestResult): + + def __init__(self, stream): + super(CsvResult, self).__init__(self._on_test) + self._write_row = csv.writer(stream).writerow + + def _on_test(self, test, status, start_time, stop_time, tags, details): + self._write_row([test.id(), status, start_time, stop_time]) + + def startTestRun(self): + super(CsvResult, self).startTestRun() + self._write_row(['test', 'status', 'start_time', 'stop_time']) |
