From d3a6be413014b112227cbdb489c62483ec4d9192 Mon Sep 17 00:00:00 2001 From: Katerina Koukiou Date: Wed, 22 Feb 2017 14:17:45 +0100 Subject: [PATCH] junitxml: Fix double system-out tags per testcase In the xml report we now have two occurences for the system-out tag if the testcase writes to stdout both on call and teardown and fails in teardown. This behaviour is against the xsd. This patch makes sure that the system-out section exists only once per testcase. --- CHANGELOG.rst | 4 ++++ _pytest/junitxml.py | 9 ++++----- testing/test_junitxml.py | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a07062437..d309125d9 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,9 @@ 3.0.7 (unreleased) ================== +* junitxml: Fix problematic case where system-out tag occured twice per testcase + element in the XML report. Thanks `@kkoukiou`_ for the PR. + * Fix regression, pytest now skips unittest correctly if run with ``--pdb`` (`#2137`_). Thanks to `@gst`_ for the report and `@mbyt`_ for the PR. @@ -31,6 +34,7 @@ .. _@gst: https://github.com/gst .. _@sirex: https://github.com/sirex .. _@vidartf: https://github.com/vidartf +.. _@kkoukiou: https://github.com/KKoukiou .. _#2137: https://github.com/pytest-dev/pytest/issues/2137 .. _#2160: https://github.com/pytest-dev/pytest/issues/2160 diff --git a/_pytest/junitxml.py b/_pytest/junitxml.py index 317382e63..3f371c9d3 100644 --- a/_pytest/junitxml.py +++ b/_pytest/junitxml.py @@ -119,7 +119,7 @@ class _NodeReporter(object): node = kind(data, message=message) self.append(node) - def _write_captured_output(self, report): + def write_captured_output(self, report): for capname in ('out', 'err'): content = getattr(report, 'capstd' + capname) if content: @@ -128,7 +128,6 @@ class _NodeReporter(object): def append_pass(self, report): self.add_stats('passed') - self._write_captured_output(report) def append_failure(self, report): # msg = str(report.longrepr.reprtraceback.extraline) @@ -147,7 +146,6 @@ class _NodeReporter(object): fail = Junit.failure(message=message) fail.append(bin_xml_escape(report.longrepr)) self.append(fail) - self._write_captured_output(report) def append_collect_error(self, report): # msg = str(report.longrepr.reprtraceback.extraline) @@ -165,7 +163,6 @@ class _NodeReporter(object): msg = "test setup failure" self._add_simple( Junit.error, msg, report.longrepr) - self._write_captured_output(report) def append_skipped(self, report): if hasattr(report, "wasxfail"): @@ -180,7 +177,7 @@ class _NodeReporter(object): Junit.skipped("%s:%s: %s" % (filename, lineno, skipreason), type="pytest.skip", message=skipreason)) - self._write_captured_output(report) + self.write_captured_output(report) def finalize(self): data = self.to_xml().unicode(indent=0) @@ -345,6 +342,8 @@ class LogXML(object): reporter.append_skipped(report) self.update_testcase_duration(report) if report.when == "teardown": + reporter = self._opentestcase(report) + reporter.write_captured_output(report) self.finalize(report) def update_testcase_duration(self, report): diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index abbc9cd33..d167f735d 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -557,6 +557,25 @@ class TestPython: systemout = pnode.find_first_by_tag("system-err") assert "hello-stderr" in systemout.toxml() + def test_avoid_double_stdout(self, testdir): + testdir.makepyfile(""" + import sys + import pytest + + @pytest.fixture + def arg(request): + yield + sys.stdout.write('hello-stdout teardown') + raise ValueError() + def test_function(arg): + sys.stdout.write('hello-stdout call') + """) + result, dom = runandparse(testdir) + node = dom.find_first_by_tag("testsuite") + pnode = node.find_first_by_tag("testcase") + systemout = pnode.find_first_by_tag("system-out") + assert "hello-stdout call" in systemout.toxml() + assert "hello-stdout teardown" in systemout.toxml() def test_mangle_test_address(): from _pytest.junitxml import mangle_test_address