diff --git a/changelog/3533.bugfix.rst b/changelog/3533.bugfix.rst new file mode 100644 index 00000000000..89f13645860 --- /dev/null +++ b/changelog/3533.bugfix.rst @@ -0,0 +1 @@ +Fix unescaped XML raw objects in JUnit report for skipped tests diff --git a/src/_pytest/junitxml.py b/src/_pytest/junitxml.py index ac00c772a1a..a39c94c1394 100644 --- a/src/_pytest/junitxml.py +++ b/src/_pytest/junitxml.py @@ -221,12 +221,14 @@ def append_skipped(self, report): else: filename, lineno, skipreason = report.longrepr if skipreason.startswith("Skipped: "): - skipreason = bin_xml_escape(skipreason[9:]) + skipreason = skipreason[9:] + details = "%s:%s: %s" % (filename, lineno, skipreason) + self.append( Junit.skipped( - "%s:%s: %s" % (filename, lineno, skipreason), + bin_xml_escape(details), type="pytest.skip", - message=skipreason, + message=bin_xml_escape(skipreason), ) ) self.write_captured_output(report) diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index 29d3f7f6ec1..079b01f3201 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -1222,3 +1222,19 @@ def test_func(): assert result.ret == 0 node = dom.find_first_by_tag("testsuite") node.assert_attr(name=expected) + + +def test_escaped_skipreason_issue3533(testdir): + testdir.makepyfile( + """ + import pytest + @pytest.mark.skip(reason='1 <> 2') + def test_skip(): + pass + """ + ) + _, dom = runandparse(testdir) + node = dom.find_first_by_tag("testcase") + snode = node.find_first_by_tag("skipped") + assert "1 <> 2" in snode.text + snode.assert_attr(message="1 <> 2")