diff options
| author | Robert Collins <robertc@robertcollins.net> | 2009-10-05 06:20:25 +1100 |
|---|---|---|
| committer | Robert Collins <robertc@robertcollins.net> | 2009-10-05 06:20:25 +1100 |
| commit | aa757dce0d1ca43a66a5f008e05699a0230b0d59 (patch) | |
| tree | 15236c95ed2aebd00678d32cfdcb021a85e66713 /python | |
| parent | 1bb81bd80c26f41555f676d9f6b164be9c061e61 (diff) | |
| download | subunit-git-aa757dce0d1ca43a66a5f008e05699a0230b0d59.tar.gz | |
Hook addFailure to to details.
Diffstat (limited to 'python')
| -rw-r--r-- | python/subunit/__init__.py | 62 | ||||
| -rw-r--r-- | python/subunit/content.py | 4 | ||||
| -rw-r--r-- | python/subunit/tests/test_test_protocol.py | 25 |
3 files changed, 71 insertions, 20 deletions
diff --git a/python/subunit/__init__.py b/python/subunit/__init__.py index 4edd69d..9d021fe 100644 --- a/python/subunit/__init__.py +++ b/python/subunit/__init__.py @@ -46,8 +46,9 @@ will either lose fidelity (for instance, folding expected failures to success in Python versions < 2.7 or 3.1), or discard the extended data (for extra details, tags, timestamping and progress markers). -The test outcome methods ``addSuccess`` take an optional keyword parameter -``details`` which can be used instead of the usual python unittest parameter. +The test outcome methods ``addSuccess``, ``addFailure`` take an optional +keyword parameter ``details`` which can be used instead of the usual python +unittest parameter. When used the value of details should be a dict from ``string`` to ``subunit.content.Content`` objects. This is a draft API being worked on with the Python Testing In Python mail list, with the goal of permitting a common @@ -479,11 +480,28 @@ class TestProtocolClient(unittest.TestResult): self._stream.write("%s\n" % line) self._stream.write("]\n") - def addFailure(self, test, error): - """Report a failure in test test.""" - self._stream.write("failure: %s [\n" % test.id()) - for line in self._exc_info_to_string(error, test).splitlines(): - self._stream.write("%s\n" % line) + def addFailure(self, test, error=None, details=None): + """Report a failure in test test. + + Only one of error and details should be provided: conceptually there + are two separate methods: + addFailure(self, test, error) + addFailure(self, test, details) + + :param error: Standard unittest positional argument form - an + exc_info tuple. + :param details: New Testing-in-python drafted API; a dict from string + to subunit.Content objects. + """ + self._stream.write("failure: %s" % test.id()) + if error is None and details is None: + raise ValueError + if error is not None: + self._stream.write(" [\n") + for line in self._exc_info_to_string(error, test).splitlines(): + self._stream.write("%s\n" % line) + else: + self._write_details(details) self._stream.write("]\n") def addSkip(self, test, reason): @@ -498,14 +516,7 @@ class TestProtocolClient(unittest.TestResult): if not details: self._stream.write("\n") else: - self._stream.write(" [ multipart\n") - for name, content in details.iteritems(): - self._stream.write("Content-Type: %s/%s\n" % - (content.content_type.type, content.content_type.subtype)) - self._stream.write("%s\n" % name) - for bytes in content.iter_bytes(): - self._stream.write("%d\n%s" % (len(bytes), bytes)) - self._stream.write("0\n") + self._write_details(details) self._stream.write("]\n") def startTest(self, test): @@ -544,6 +555,27 @@ class TestProtocolClient(unittest.TestResult): time.year, time.month, time.day, time.hour, time.minute, time.second, time.microsecond)) + def _write_details(self, details): + """Output details to the stream. + + :param details: An extended details dict for a test outcome. + """ + self._stream.write(" [ multipart\n") + for name, content in sorted(details.iteritems()): + self._stream.write("Content-Type: %s/%s" % + (content.content_type.type, content.content_type.subtype)) + parameters = content.content_type.parameters + if parameters: + self._stream.write(";") + param_strs = [] + for param, value in parameters.iteritems(): + param_strs.append("%s=%s" % (param, value)) + self._stream.write(",".join(param_strs)) + self._stream.write("\n%s\n" % name) + for bytes in content.iter_bytes(): + self._stream.write("%d\n%s" % (len(bytes), bytes)) + self._stream.write("0\n") + def done(self): """Obey the testtools result.done() interface.""" diff --git a/python/subunit/content.py b/python/subunit/content.py index cd3ad60..160a58a 100644 --- a/python/subunit/content.py +++ b/python/subunit/content.py @@ -63,5 +63,5 @@ class TracebackContent(Content): {"language": "python"}) self._result = TestResult() super(TracebackContent, self).__init__(content_type, - lambda:self._result._exc_info_to_string(err, - subunit.RemotedTestCase(''))) + lambda:[self._result._exc_info_to_string(err, + subunit.RemotedTestCase(''))]) diff --git a/python/subunit/tests/test_test_protocol.py b/python/subunit/tests/test_test_protocol.py index f505626..1b48290 100644 --- a/python/subunit/tests/test_test_protocol.py +++ b/python/subunit/tests/test_test_protocol.py @@ -21,7 +21,7 @@ import os import sys import subunit -from subunit.content import Content +from subunit.content import Content, TracebackContent from subunit.content_type import ContentType import subunit.iso8601 as iso8601 @@ -1056,6 +1056,9 @@ class TestTestProtocolClient(unittest.TestCase): self.test = TestTestProtocolClient("test_start_test") self.sample_details = {'something':Content( ContentType('text', 'plain'), lambda:['serialised\nform'])} + self.sample_tb_details = dict(self.sample_details) + self.sample_tb_details['traceback'] = TracebackContent( + subunit.RemoteError("boo qux")) def test_start_test(self): """Test startTest on a TestProtocolClient.""" @@ -1074,13 +1077,13 @@ class TestTestProtocolClient(unittest.TestCase): self.io.getvalue(), "successful: %s\n" % self.test.id()) def test_add_success_details(self): - """Test addSuccess on a TestProtocolClient.""" + """Test addSuccess on a TestProtocolClient with details.""" self.protocol.addSuccess(self.test, details=self.sample_details) self.assertEqual( self.io.getvalue(), "successful: %s [ multipart\n" "Content-Type: text/plain\n" "something\n" - "15\nserialised\nform0\n]\n"% self.test.id()) + "15\nserialised\nform0\n]\n" % self.test.id()) def test_add_failure(self): """Test addFailure on a TestProtocolClient.""" @@ -1090,6 +1093,22 @@ class TestTestProtocolClient(unittest.TestCase): self.io.getvalue(), 'failure: %s [\nRemoteException: boo qux\n]\n' % self.test.id()) + def test_add_failure_details(self): + """Test addFailure on a TestProtocolClient with details.""" + self.protocol.addFailure( + self.test, details=self.sample_tb_details) + self.assertEqual( + self.io.getvalue(), + "failure: %s [ multipart\n" + "Content-Type: text/plain\n" + "something\n" + "15\nserialised\nform0\n" + "Content-Type: text/x-traceback;language=python\n" + "traceback\n" + "25\nRemoteException: boo qux\n0\n" + "]\n" % self.test.id()) + + def test_add_error(self): """Test stopTest on a TestProtocolClient.""" self.protocol.addError( |
