Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JUnit XML: Escape error messages in setup/teardown #10190

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Expand Up @@ -313,6 +313,7 @@ Seth Junot
Shantanu Jain
Shubham Adep
Simon Gomizelj
Simon Holesch
Simon Kerr
Skylar Downes
Srinivas Reddy Thatiparthy
Expand Down
1 change: 1 addition & 0 deletions changelog/10190.bugfix.rst
@@ -0,0 +1 @@
Invalid XML characters in setup or teardown error messages are now properly escaped for JUnit XML reports.
2 changes: 1 addition & 1 deletion src/_pytest/junitxml.py
Expand Up @@ -231,7 +231,7 @@ def append_error(self, report: TestReport) -> None:
msg = f'failed on teardown with "{reason}"'
else:
msg = f'failed on setup with "{reason}"'
self._add_simple("error", msg, str(report.longrepr))
self._add_simple("error", bin_xml_escape(msg), str(report.longrepr))

def append_skipped(self, report: TestReport) -> None:
if hasattr(report, "wasxfail"):
Expand Down
22 changes: 22 additions & 0 deletions testing/test_junitxml.py
Expand Up @@ -1625,6 +1625,28 @@ def test_skip():
snode.assert_attr(message="1 <> 2")


def test_escaped_setup_teardown_error(
pytester: Pytester, run_and_parse: RunAndParse
) -> None:
pytester.makepyfile(
"""
import pytest

@pytest.fixture()
def my_setup():
raise Exception("error: \033[31mred\033[m")

def test_esc(my_setup):
pass
"""
)
_, dom = run_and_parse()
node = dom.find_first_by_tag("testcase")
snode = node.find_first_by_tag("error")
assert "#x1B[31mred#x1B[m" in snode["message"]
assert "#x1B[31mred#x1B[m" in snode.text


@parametrize_families
def test_logging_passing_tests_disabled_does_not_log_test_output(
pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
Expand Down