# HG changeset patch # User hodgestar # Date 1271792719 0 # Node ID 77ddb8c210d8f9eed041e52b6783fab8eaff76a3 # Parent 7c8b6a329e120875ce6163165bc140b5809ff084 Fix and tests for failure when parsing py.test --junitxml tracebacks (patch from Torsten Landschoff). See #562. diff --git a/bitten/build/javatools.py b/bitten/build/javatools.py --- 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' diff --git a/bitten/build/tests/__init__.py b/bitten/build/tests/__init__.py --- 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 diff --git a/bitten/build/tests/javatools.py b/bitten/build/tests/javatools.py --- 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 = """ + %(body)s + +""" + 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 = '' + 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 = '' \ + + 'request = <FuncargRequest for <Function...' \ + + '' + 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 =