diff --git a/AUTHORS b/AUTHORS index f3dafb999..90e639234 100644 --- a/AUTHORS +++ b/AUTHORS @@ -48,6 +48,7 @@ David Vierra Denis Kirisov Diego Russo Dmitry Dygalo +Dmitry Pribysh Duncan Betts Edison Gustavo Muenz Edoardo Batini diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3f4814d8e..06bbdf120 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,8 @@ New Features ------------ +* fix `#533`_: Added ``junit_suite_name`` ini option to specify root `` name for JUnit XML reports + * Added an ini option ``doctest_encoding`` to specify which encoding to use for doctest files. Thanks `@wheerd`_ for the PR (`#2101`_). @@ -105,6 +107,7 @@ Bug Fixes .. _@ojii: https://github.com/ojii +.. _#533: https://github.com/pytest-dev/pytest/issues/533 .. _#1407: https://github.com/pytest-dev/pytest/issues/1407 .. _#1512: https://github.com/pytest-dev/pytest/issues/1512 .. _#1821: https://github.com/pytest-dev/pytest/issues/1821 diff --git a/_pytest/junitxml.py b/_pytest/junitxml.py index 4bd334a16..301633706 100644 --- a/_pytest/junitxml.py +++ b/_pytest/junitxml.py @@ -226,13 +226,14 @@ def pytest_addoption(parser): metavar="str", default=None, help="prepend prefix to classnames in junit-xml output") + parser.addini("junit_suite_name", "Test suite name for JUnit report", default="pytest") def pytest_configure(config): xmlpath = config.option.xmlpath # prevent opening xmllog on slave nodes (xdist) if xmlpath and not hasattr(config, 'slaveinput'): - config._xml = LogXML(xmlpath, config.option.junitprefix) + config._xml = LogXML(xmlpath, config.option.junitprefix, config.getini("junit_suite_name")) config.pluginmanager.register(config._xml) @@ -259,10 +260,11 @@ def mangle_test_address(address): class LogXML(object): - def __init__(self, logfile, prefix): + def __init__(self, logfile, prefix, suite_name="pytest"): logfile = os.path.expanduser(os.path.expandvars(logfile)) self.logfile = os.path.normpath(os.path.abspath(logfile)) self.prefix = prefix + self.suite_name = suite_name self.stats = dict.fromkeys([ 'error', 'passed', @@ -422,7 +424,7 @@ class LogXML(object): logfile.write(Junit.testsuite( self._get_global_properties_node(), [x.to_xml() for x in self.node_reporters_ordered], - name="pytest", + name=self.suite_name, errors=self.stats['error'], failures=self.stats['failure'], skips=self.stats['skipped'], diff --git a/doc/en/usage.rst b/doc/en/usage.rst index f6c20a978..763328f5a 100644 --- a/doc/en/usage.rst +++ b/doc/en/usage.rst @@ -177,6 +177,15 @@ integration servers, use this invocation:: to create an XML file at ``path``. +.. versionadded:: 3.1 + +To set the name of the root test suite xml item, you can configure the ``junit_suite_name`` option in your config file: + +.. code-block:: ini + + [pytest] + junit_suite_name = my_suite + record_xml_property ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index 7003d9f5f..bc637b035 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -616,6 +616,9 @@ def test_dont_configure_on_slaves(tmpdir): self.pluginmanager = self self.option = self + def getini(self, name): + return "pytest" + junitprefix = None # XXX: shouldnt need tmpdir ? xmlpath = str(tmpdir.join('junix.xml')) @@ -1032,3 +1035,26 @@ def test_url_property(testdir): test_case = minidom.parse(str(path)).getElementsByTagName('testcase')[0] assert (test_case.getAttribute('url') == test_url), "The URL did not get written to the xml" + + +@pytest.mark.parametrize('suite_name', ['my_suite', '']) +def test_set_suite_name(testdir, suite_name): + if suite_name: + testdir.makeini(""" + [pytest] + junit_suite_name={0} + """.format(suite_name)) + expected = suite_name + else: + expected = 'pytest' + testdir.makepyfile(""" + import pytest + + def test_func(): + pass + """) + result, dom = runandparse(testdir) + assert result.ret == 0 + node = dom.find_first_by_tag("testsuite") + node.assert_attr(name=expected) +