Mercurial > bitten > bitten-test
changeset 741:77ddb8c210d8
Fix and tests for failure when parsing py.test --junitxml tracebacks (patch from Torsten Landschoff). See #562.
author | hodgestar |
---|---|
date | Tue, 20 Apr 2010 19:45:19 +0000 |
parents | 7c8b6a329e12 |
children | 5e274fc552c3 |
files | bitten/build/javatools.py bitten/build/tests/__init__.py bitten/build/tests/javatools.py |
diffstat | 3 files changed, 84 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/bitten/build/javatools.py +++ b/bitten/build/javatools.py @@ -101,6 +101,24 @@ if not error_logged and cmdline.returncode != 0: ctxt.error('Ant failed (%s)' % cmdline.returncode) + +def _fix_traceback(result): + """ + Sometimes the traceback isn't prefixed with the exception type and + message, so add it in if needed. + """ + attr = result[0].attr + tracebackprefix = "" + # py.test does not include the type tag in some cases so don't do this + # fix when it is missing + if "type" in attr: + tracebackprefix = "%s: %s" % (attr['type'], attr.get('message', '')) + if result[0].gettext().startswith(tracebackprefix): + return result[0].gettext() + else: + return "\n".join((tracebackprefix, result[0].gettext())) + + def junit(ctxt, file_=None, srcdir=None): """Extract test results from a JUnit XML report. @@ -132,16 +150,7 @@ result = list(testcase.children()) if result: test.attr['status'] = result[0].name - # Sometimes the traceback isn't prefixed with the - # exception type and message, so add it in if needed - tracebackprefix = "%s: %s" % (result[0].attr['type'], - result[0].attr.get('message', '')) - if result[0].gettext().startswith(tracebackprefix): - test.append(xmlio.Element('traceback')[ - result[0].gettext()]) - else: - test.append(xmlio.Element('traceback')[ - "\n".join((tracebackprefix, result[0].gettext()))]) + test.append(xmlio.Element('traceback')[_fix_traceback(result)]) failed += 1 else: test.attr['status'] = 'success'
--- a/bitten/build/tests/__init__.py +++ b/bitten/build/tests/__init__.py @@ -12,7 +12,7 @@ from bitten.build.tests import api, config, ctools, hgtools, \ monotools, phptools, pythontools, \ - xmltools + xmltools, javatools def suite(): suite = unittest.TestSuite() @@ -23,6 +23,7 @@ suite.addTest(monotools.suite()) suite.addTest(phptools.suite()) suite.addTest(pythontools.suite()) + suite.addTest(javatools.suite()) suite.addTest(xmltools.suite()) return suite
--- a/bitten/build/tests/javatools.py +++ b/bitten/build/tests/javatools.py @@ -9,6 +9,7 @@ # you should have received as part of this distribution. The terms # are also available at http://bitten.edgewall.org/wiki/License. +import os import os.path import shutil import tempfile @@ -119,10 +120,72 @@ self.assertEqual(0, elem.attr['lines']) self.assertEqual(0, elem.attr['percentage']) +class PyTestTestCase(unittest.TestCase): + xml_template = """<testsuite name="%(name)s" errors="%(errors)d" + failures="%(failures)d" skips="%(skips)d" tests="%(tests)d" time="%(time)f"> + %(body)s +</testsuite> +""" + def setUp(self): + self.basedir = os.path.realpath(tempfile.mkdtemp()) + self.ctxt = Context(self.basedir) + + def tearDown(self): + shutil.rmtree(self.basedir) + + def _xml_file(self, body, name="", errors=0, failures=0, skips=0, tests=0, time=0.01): + if tests == 0: + tests = errors + failures + skips + (fd, path) = tempfile.mkstemp(prefix="junit", suffix=".xml", dir=self.basedir, text=True) + stream = os.fdopen(fd, "w") + content = self.xml_template % dict(body=body, name=name, errors=errors, + failures=failures, skips=skips, tests=tests, time=time) + stream.write(content) + stream.close() + return path + + def test_simple(self): + body = '<testcase classname="_test.test_event" name="test_simple" time="0.0002"></testcase>' + filename = self._xml_file(body, tests=1) + javatools.junit(self.ctxt, file_=filename) + type, category, generator, xml = self.ctxt.output.pop() + self.assertEqual('report', type) + self.assertEqual('test', category) + self.assertEqual(1, len(xml.children)) + + elem = xml.children[0] + self.assertEqual('test', elem.name) + self.assertEqual('test_simple', elem.attr['name']) + self.assertEqual('success', elem.attr['status']) + self.assertEqual(0, len(elem.children)) + + def test_setup_fail(self): + """Check that py.test setup failures are handled""" + body = '<testcase classname="_test.test_event" name="test_simple" time="0">' \ + + '<error message="test setup failure">request = <FuncargRequest for <Function...</error>' \ + + '</testcase>' + filename = self._xml_file(body, errors=1) + javatools.junit(self.ctxt, file_=filename) + type, category, generator, xml = self.ctxt.output.pop() + self.assertEqual('report', type) + self.assertEqual('test', category) + self.assertEqual(1, len(xml.children)) + + elem = xml.children[0] + self.assertEqual('test', elem.name) + self.assertEqual('test_simple', elem.attr['name']) + self.assertEqual('error', elem.attr['status']) + self.assertEqual(1, len(elem.children)) + + trace = elem.children[0] + self.assertEqual('traceback', trace.name) + self.assertEqual(1, len(trace.children)) + self.assertEqual('request = <FuncargRequest for <Function...', trace.children[0]) def suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(CoberturaTestCase, 'test')) + suite.addTest(unittest.makeSuite(PyTestTestCase, 'test')) return suite if __name__ == '__main__':