diff --git a/pytest_nunit/nunit.py b/pytest_nunit/nunit.py index 2f19e58..10ac311 100644 --- a/pytest_nunit/nunit.py +++ b/pytest_nunit/nunit.py @@ -12,7 +12,8 @@ FailureType, PropertyBagType, PropertyType, ReasonType, TestCaseElementType, TestFilterType, TestResultType, TestRunStateType, TestRunType, - TestStatusType, TestSuiteElementType, + TestStatusType, TestSuiteElementType, SettingsType, + SettingType, TestSuiteTypeType, ValueMatchFilterType) FRAMEWORK_VERSION = "3.6.2" # Nunit version this was based on @@ -116,6 +117,18 @@ def _format_filters(filters_): ) +def _format_settings(settings): + if not settings: + return None + + return SettingsType( + setting=[ + SettingType(item=None, name=name, value=value) + for name, value in sorted(settings.items()) + ] + ) + + def _getlocale(): # See https://github.com/pytest-dev/pytest-nunit/pull/73 with warnings.catch_warnings(): @@ -212,7 +225,7 @@ def test_suites(self): property=[PropertyType(name="python_version", value=sys.version)] ), environment=self.environment, - settings=None, + settings=_format_settings(self.nunitxml.settings), failure=None, reason=None, output=None, diff --git a/pytest_nunit/plugin.py b/pytest_nunit/plugin.py index f47b2b9..a422c18 100644 --- a/pytest_nunit/plugin.py +++ b/pytest_nunit/plugin.py @@ -45,6 +45,26 @@ def max_with_default(seq, default): max_with_default = max +def _stringify_setting(value): + if value is None: + return "" + if isinstance(value, (list, tuple)): + return " ".join(str(item) for item in value) + return str(value) + + +def _collect_runtime_settings(config): + rootdir = getattr(config, "rootpath", getattr(config, "rootdir", "")) + inifile = getattr(config, "inipath", getattr(config, "inifile", None)) + settings = { + "rootdir": rootdir, + "inifile": inifile, + "nunit_suite_name": config.getini("nunit_suite_name"), + "nunit_attach_on": config.getini("nunit_attach_on"), + } + return {name: _stringify_setting(value) for name, value in settings.items()} + + def pytest_addoption(parser): """Allow export settings on CLI.""" group = parser.getgroup("terminal reporting") @@ -111,6 +131,7 @@ def pytest_configure(config): show_user_domain=config.getini("nunit_show_user_domain"), attach_on=config.getini("nunit_attach_on"), filters=filters, + settings=_collect_runtime_settings(config), ) config.pluginmanager.register(config._nunitxml) @@ -267,6 +288,7 @@ def __init__( show_user_domain=False, attach_on="any", filters=None, + settings=None, ): logfile = os.path.expanduser(os.path.expandvars(logfile)) self.logfile = os.path.normpath(os.path.abspath(logfile)) @@ -284,6 +306,7 @@ def __init__( log.debug("Attach on criteria : %s", attach_on) self.idrefindex = 100 # Create a unique ID counter self.filters = filters + self.settings = settings or {} self.node_descriptions = defaultdict(str) self.module_descriptions = defaultdict(str) diff --git a/tests/integration/test_config.py b/tests/integration/test_config.py index 222d751..804b64d 100644 --- a/tests/integration/test_config.py +++ b/tests/integration/test_config.py @@ -39,3 +39,46 @@ def test_basic(): assert out["test-suite"]["@failed"] == 0 assert out["test-suite"]["@skipped"] == 0 assert out["test-suite"]["test-case"]["@name"] == "test1.test_prefix.py::test_basic" + + +def test_runtime_settings(testdir, tmpdir): + """ + Test that pytest runtime settings are included in suite metadata. + """ + testdir.makeini( + """ + [pytest] + nunit_suite_name = Configured suite + nunit_attach_on = fail + """ + ) + testdir.makepyfile( + """ + def test_basic(): + assert 1 == 1 + """ + ) + outfile = tmpdir.join("out.xml") + outfile_pth = str(outfile) + + result = testdir.runpytest("-v", "--nunit-xml=" + outfile_pth) + result.stdout.fnmatch_lines(["*test_basic PASSED*"]) + assert result.ret == 0 + + xs = xmlschema.XMLSchema( + os.path.join( + os.path.abspath(os.path.dirname(__file__)), + "../../ext/nunit-src/TestResult.xsd", + ), + validation="lax", + ) + out = xs.to_dict(outfile_pth) + settings = { + setting["@name"]: setting["@value"] + for setting in out["test-suite"]["settings"]["setting"] + } + + assert settings["nunit_suite_name"] == "Configured suite" + assert settings["nunit_attach_on"] == "fail" + assert settings["rootdir"] == str(testdir.tmpdir) + assert settings["inifile"].endswith(".ini")