diff options
| author | Robert Collins <robertc@robertcollins.net> | 2014-08-24 17:54:36 +1200 |
|---|---|---|
| committer | Robert Collins <robertc@robertcollins.net> | 2014-08-24 17:54:36 +1200 |
| commit | 63ea73bf3ad9106907eefa21e6f858040cfa0ed8 (patch) | |
| tree | 26c1c2a01c0741680493d8e0196615a65a15099c /python | |
| parent | d068eedebb3bfa97386550825f2dc6ecc7d9e352 (diff) | |
| download | subunit-git-63ea73bf3ad9106907eefa21e6f858040cfa0ed8.tar.gz | |
0.0.19
------
IMPROVEMENTS
~~~~~~~~~~~~
* ``subunit.run`` in Python will now exit 0 as long as the test stream has
been generated correctly - this has always been the intent but API friction
with testtools had prevented it working.
(Robert Collins)
Diffstat (limited to 'python')
| -rw-r--r-- | python/subunit/__init__.py | 2 | ||||
| -rwxr-xr-x | python/subunit/run.py | 42 | ||||
| -rw-r--r-- | python/subunit/tests/test_run.py | 46 |
3 files changed, 64 insertions, 26 deletions
diff --git a/python/subunit/__init__.py b/python/subunit/__init__.py index 8764d45..ff952c3 100644 --- a/python/subunit/__init__.py +++ b/python/subunit/__init__.py @@ -153,7 +153,7 @@ from subunit.v2 import ByteStreamToStreamResult, StreamResultToBytes # If the releaselevel is 'final', then the tarball will be major.minor.micro. # Otherwise it is major.minor.micro~$(revno). -__version__ = (0, 0, 18, 'final', 0) +__version__ = (0, 0, 19, 'final', 0) PROGRESS_SET = 0 PROGRESS_CUR = 1 diff --git a/python/subunit/run.py b/python/subunit/run.py index 7e4d783..cf9cc01 100755 --- a/python/subunit/run.py +++ b/python/subunit/run.py @@ -40,15 +40,21 @@ from testtools.run import ( class SubunitTestRunner(object): - def __init__(self, verbosity=None, failfast=None, buffer=None, stream=None): + def __init__(self, verbosity=None, failfast=None, buffer=None, stream=None, + stdout=None): """Create a TestToolsTestRunner. :param verbosity: Ignored. :param failfast: Stop running tests at the first failure. :param buffer: Ignored. + :param stream: Upstream unittest stream parameter. + :param stdout: Testtools stream parameter. + + Either stream or stdout can be supplied, and stream will take + precedence. """ self.failfast = failfast - self.stream = stream or sys.stdout + self.stream = stream or stdout or sys.stdout def run(self, test): "Run the given test case or test suite." @@ -112,19 +118,27 @@ class SubunitTestProgram(TestProgram): sys.exit(2) -def main(): - # Disable the default buffering, for Python 2.x where pdb doesn't do it - # on non-ttys. - stream = get_default_formatter() +def main(argv=None, stdout=None): + if argv is None: + argv = sys.argv runner = SubunitTestRunner - # Patch stdout to be unbuffered, so that pdb works well on 2.6/2.7. - binstdout = io.open(sys.stdout.fileno(), 'wb', 0) - if sys.version_info[0] > 2: - sys.stdout = io.TextIOWrapper(binstdout, encoding=sys.stdout.encoding) - else: - sys.stdout = binstdout - SubunitTestProgram(module=None, argv=sys.argv, testRunner=runner, - stdout=sys.stdout) + # stdout is None except in unit tests. + if stdout is None: + stdout = sys.stdout + # XXX: This is broken code- SUBUNIT_FORMATTER is not being honoured. + stream = get_default_formatter() + # Disable the default buffering, for Python 2.x where pdb doesn't do it + # on non-ttys. + if hasattr(stdout, 'fileno'): + # Patch stdout to be unbuffered, so that pdb works well on 2.6/2.7. + binstdout = io.open(stdout.fileno(), 'wb', 0) + if sys.version_info[0] > 2: + sys.stdout = io.TextIOWrapper(binstdout, encoding=sys.stdout.encoding) + else: + sys.stdout = binstdout + stdout = sys.stdout + SubunitTestProgram(module=None, argv=argv, testRunner=runner, + stdout=stdout, exit=False) if __name__ == '__main__': diff --git a/python/subunit/tests/test_run.py b/python/subunit/tests/test_run.py index 6ac84e1..d92ed04 100644 --- a/python/subunit/tests/test_run.py +++ b/python/subunit/tests/test_run.py @@ -14,10 +14,12 @@ # limitations under that license. # -from testtools.compat import BytesIO +import io import unittest from testtools import PlaceHolder, TestCase +from testtools.compat import _b +from testtools.matchers import StartsWith from testtools.testresult.doubles import StreamResult import subunit @@ -28,37 +30,59 @@ from subunit.run import SubunitTestRunner class TestSubunitTestRunner(TestCase): def test_includes_timing_output(self): - io = BytesIO() - runner = SubunitTestRunner(stream=io) + bytestream = io.BytesIO() + runner = SubunitTestRunner(stream=bytestream) test = PlaceHolder('name') runner.run(test) - io.seek(0) + bytestream.seek(0) eventstream = StreamResult() - subunit.ByteStreamToStreamResult(io).run(eventstream) + subunit.ByteStreamToStreamResult(bytestream).run(eventstream) timestamps = [event[-1] for event in eventstream._events if event is not None] self.assertNotEqual([], timestamps) def test_enumerates_tests_before_run(self): - io = BytesIO() - runner = SubunitTestRunner(stream=io) + bytestream = io.BytesIO() + runner = SubunitTestRunner(stream=bytestream) test1 = PlaceHolder('name1') test2 = PlaceHolder('name2') case = unittest.TestSuite([test1, test2]) runner.run(case) - io.seek(0) + bytestream.seek(0) eventstream = StreamResult() - subunit.ByteStreamToStreamResult(io).run(eventstream) + subunit.ByteStreamToStreamResult(bytestream).run(eventstream) self.assertEqual([ ('status', 'name1', 'exists'), ('status', 'name2', 'exists'), ], [event[:3] for event in eventstream._events[:2]]) def test_list_errors_if_errors_from_list_test(self): - io = BytesIO() - runner = SubunitTestRunner(stream=io) + bytestream = io.BytesIO() + runner = SubunitTestRunner(stream=bytestream) def list_test(test): return [], ['failed import'] self.patch(run, 'list_test', list_test) exc = self.assertRaises(SystemExit, runner.list, None) self.assertEqual((2,), exc.args) + + class FailingTest(TestCase): + def test_fail(self): + 1/0 + + def test_exits_zero_when_tests_fail(self): + bytestream = io.BytesIO() + stream = io.TextIOWrapper(bytestream, encoding="utf8") + try: + self.assertEqual(None, run.main( + argv=["progName", "subunit.tests.test_run.TestSubunitTestRunner.FailingTest"], + stdout=stream)) + except SystemExit: + self.fail("SystemExit raised") + self.assertThat(bytestream.getvalue(), StartsWith(_b('\xb3'))) + + def test_exits_nonzero_when_execution_errors(self): + bytestream = io.BytesIO() + stream = io.TextIOWrapper(bytestream, encoding="utf8") + exc = self.assertRaises(Exception, run.main, + argv=["progName", "subunit.tests.test_run.TestSubunitTestRunner.MissingTest"], + stdout=stream) |
