diff --git a/CHANGELOG b/CHANGELOG index a3d6b41c3..b17fa69df 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -17,6 +17,9 @@ New features (thanks Ronny Pfannschmidt) +- introduce '--junitprefix=STR' option to prepend a prefix + to all reports in the junitxml file. + - Funcarg factories can now dynamically apply a marker to a test invocation. This is particularly useful if a factory provides parameters to a test which you expect-to-fail: diff --git a/py/_plugin/pytest_junitxml.py b/py/_plugin/pytest_junitxml.py index 4fca5ffe3..82910114e 100644 --- a/py/_plugin/pytest_junitxml.py +++ b/py/_plugin/pytest_junitxml.py @@ -11,11 +11,14 @@ def pytest_addoption(parser): group.addoption('--junitxml', action="store", dest="xmlpath", metavar="path", default=None, help="create junit-xml style report file at given path.") + group.addoption('--junitprefix', action="store", dest="junitprefix", + metavar="str", default=None, + help="prepend prefix to classnames in junit-xml output") def pytest_configure(config): xmlpath = config.option.xmlpath if xmlpath: - config._xml = LogXML(xmlpath) + config._xml = LogXML(xmlpath, config.option.junitprefix) config.pluginmanager.register(config._xml) def pytest_unconfigure(config): @@ -25,18 +28,25 @@ def pytest_unconfigure(config): config.pluginmanager.unregister(xml) class LogXML(object): - def __init__(self, logfile): + def __init__(self, logfile, prefix): self.logfile = logfile + self.prefix = prefix self.test_logs = [] self.passed = self.skipped = 0 self.failed = self.errors = 0 self._durations = {} def _opentestcase(self, report): - node = report.item - d = {'time': self._durations.pop(report.item, "0")} + if hasattr(report, 'item'): + node = report.item + else: + node = report.collector + d = {'time': self._durations.pop(node, "0")} names = [x.replace(".py", "") for x in node.listnames() if x != "()"] - d['classname'] = ".".join(names[:-1]) + classnames = names[:-1] + if self.prefix: + classnames.insert(0, self.prefix) + d['classname'] = ".".join(classnames) d['name'] = py.xml.escape(names[-1]) attrs = ['%s="%s"' % item for item in sorted(d.items())] self.test_logs.append("\n" % " ".join(attrs)) @@ -66,17 +76,8 @@ class LogXML(object): self.failed += 1 self._closetestcase() - def _opentestcase_collectfailure(self, report): - node = report.collector - d = {'time': '???'} - names = [x.replace(".py", "") for x in node.listnames() if x != "()"] - d['classname'] = ".".join(names[:-1]) - d['name'] = py.xml.escape(names[-1]) - attrs = ['%s="%s"' % item for item in sorted(d.items())] - self.test_logs.append("\n" % " ".join(attrs)) - def append_collect_failure(self, report): - self._opentestcase_collectfailure(report) + self._opentestcase(report) #msg = str(report.longrepr.reprtraceback.extraline) self.appendlog('%s', report.longrepr) @@ -84,7 +85,7 @@ class LogXML(object): self.errors += 1 def append_collect_skipped(self, report): - self._opentestcase_collectfailure(report) + self._opentestcase(report) #msg = str(report.longrepr.reprtraceback.extraline) self.appendlog('%s', report.longrepr) diff --git a/testing/plugin/test_pytest_junitxml.py b/testing/plugin/test_pytest_junitxml.py index ba51e4b01..a0b97e5d6 100644 --- a/testing/plugin/test_pytest_junitxml.py +++ b/testing/plugin/test_pytest_junitxml.py @@ -119,6 +119,28 @@ class TestPython: classname="test_failure_escape.test_failure_escape", name="test_func[&]") + def test_junit_prefixing(self, testdir): + testdir.makepyfile(""" + def test_func(): + assert 0 + class TestHello: + def test_hello(self): + pass + """) + result, dom = runandparse(testdir, "--junitprefix=xyz") + assert result.ret + node = dom.getElementsByTagName("testsuite")[0] + assert_attr(node, failures=1, tests=2) + tnode = node.getElementsByTagName("testcase")[0] + assert_attr(tnode, + classname="xyz.test_junit_prefixing.test_junit_prefixing", + name="test_func") + tnode = node.getElementsByTagName("testcase")[1] + assert_attr(tnode, + classname="xyz.test_junit_prefixing.test_junit_prefixing." + "TestHello", + name="test_hello") + def test_xfailure_function(self, testdir): testdir.makepyfile(""" import py