From 28530836c9351c3b18434b9a3dc4fc1f1900a7fb Mon Sep 17 00:00:00 2001 From: TomV Date: Tue, 1 Mar 2016 15:49:55 +0000 Subject: [PATCH] issue469: add fix junit double colon split issue --- CHANGELOG.rst | 4 +++- _pytest/junitxml.py | 17 ++++++++++++++--- testing/test_junitxml.py | 25 ++++++++++++++++++++----- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d30433f3ddd..ccbbe2a79eb 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,7 +5,8 @@ * -* +* Fix (`#469`_): junit parses report.nodeid incorrectly, when params contain + ``::``. * @@ -102,6 +103,7 @@ .. _`traceback style docs`: https://pytest.org/latest/usage.html#modifying-python-traceback-printing +.. _#469: https://github.com/pytest-dev/pytest/issues/469 .. _#1422: https://github.com/pytest-dev/pytest/issues/1422 .. _#1379: https://github.com/pytest-dev/pytest/issues/1379 .. _#1366: https://github.com/pytest-dev/pytest/issues/1366 diff --git a/_pytest/junitxml.py b/_pytest/junitxml.py index 6c090f9c0c0..660d718a6a8 100644 --- a/_pytest/junitxml.py +++ b/_pytest/junitxml.py @@ -46,6 +46,8 @@ class Junit(py.xml.Namespace): del _legal_ranges del _legal_xml_re +_py_ext_re = re.compile(r"\.py$") + def bin_xml_escape(arg): def repl(matchobj): @@ -89,7 +91,7 @@ def make_properties_node(self): def record_testreport(self, testreport): assert not self.testcase - names = mangle_testnames(testreport.nodeid.split("::")) + names = mangle_test_address(testreport.nodeid) classnames = names[:-1] if self.xml.prefix: classnames.insert(0, self.xml.prefix) @@ -235,9 +237,18 @@ def pytest_unconfigure(config): config.pluginmanager.unregister(xml) -def mangle_testnames(names): - names = [x.replace(".py", "") for x in names if x != '()'] +def mangle_test_address(address): + path, possible_open_bracket, params = address.partition('[') + names = path.split("::") + try: + names.remove('()') + except ValueError: + pass + # convert file path to dotted path names[0] = names[0].replace("/", '.') + names[0] = _py_ext_re.sub("", names[0]) + # put any params back + names[-1] += possible_open_bracket + params return names diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index 99c59cb7a0b..7506efeeaaf 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -449,11 +449,12 @@ def test_function(arg): assert "hello-stderr" in systemout.toxml() -def test_mangle_testnames(): - from _pytest.junitxml import mangle_testnames - names = ["a/pything.py", "Class", "()", "method"] - newnames = mangle_testnames(names) - assert newnames == ["a.pything", "Class", "method"] +def test_mangle_test_address(): + from _pytest.junitxml import mangle_test_address + address = '::'.join( + ["a/my.py.thing.py", "Class", "()", "method", "[a-1-::]"]) + newnames = mangle_test_address(address) + assert newnames == ["a.my.py.thing", "Class", "method", "[a-1-::]"] def test_dont_configure_on_slaves(tmpdir): @@ -619,6 +620,20 @@ def test_func(char): node.assert_attr(name="test_func[#x00]") +def test_double_colon_split_issue469(testdir): + testdir.makepyfile(""" + import pytest + @pytest.mark.parametrize('param', ["double::colon"]) + def test_func(param): + pass + """) + result, dom = runandparse(testdir) + assert result.ret == 0 + node = dom.find_first_by_tag("testcase") + node.assert_attr(classname="test_double_colon_split_issue469") + node.assert_attr(name='test_func[double::colon]') + + def test_unicode_issue368(testdir): path = testdir.tmpdir.join("test.xml") log = LogXML(str(path), None)