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 4a3c165cc..b1852675d 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`_). @@ -86,6 +88,10 @@ Changes the documentation on different platforms. Thanks `@RonnyPfannschmidt`_ for the PR. +* fix `#2391`_: consider pytest_plugins on all plugin modules + Thansks `@RonnyPfannschmidt`_ for the PR. + + Bug Fixes --------- @@ -107,6 +113,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 @@ -118,8 +125,9 @@ Bug Fixes .. _#2166: https://github.com/pytest-dev/pytest/pull/2166 .. _#2147: https://github.com/pytest-dev/pytest/issues/2147 .. _#2208: https://github.com/pytest-dev/pytest/issues/2208 -.. _#2228: https://github.com/pytest-dev/pytest/issues/2228 +.. _#2228: https://github.com/pytest-dev/pytest/issues/2228 .. _#2308: https://github.com/pytest-dev/pytest/issues/2308 +.. _#2391: https://github.com/pytest-dev/pytest/issues/2391 3.0.8 (unreleased) diff --git a/_pytest/config.py b/_pytest/config.py index 7c8fad79f..0a79cb5b1 100644 --- a/_pytest/config.py +++ b/_pytest/config.py @@ -8,7 +8,8 @@ import warnings import py # DON't import pytest here because it causes import cycle troubles -import sys, os +import sys +import os import _pytest._code import _pytest.hookspec # the extension point definitions import _pytest.assertion @@ -252,6 +253,9 @@ class PytestPluginManager(PluginManager): if ret: self.hook.pytest_plugin_registered.call_historic( kwargs=dict(plugin=plugin, manager=self)) + + if isinstance(plugin, types.ModuleType): + self.consider_module(plugin) return ret def getplugin(self, name): @@ -396,8 +400,7 @@ class PytestPluginManager(PluginManager): self.import_plugin(arg) def consider_conftest(self, conftestmodule): - if self.register(conftestmodule, name=conftestmodule.__file__): - self.consider_module(conftestmodule) + self.register(conftestmodule, name=conftestmodule.__file__) def consider_env(self): self._import_plugin_specs(os.environ.get("PYTEST_PLUGINS")) @@ -441,7 +444,6 @@ class PytestPluginManager(PluginManager): else: mod = sys.modules[importspec] self.register(mod, modname) - self.consider_module(mod) def _get_plugin_specs_as_list(specs): 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) +