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

Allow user to select if he wants log, std-out/err in junit capture xml file, and respect his decision #6469

Merged
merged 1 commit into from
Jan 16, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ Ilya Konstantinov
Ionuț Turturică
Iwan Briquemont
Jaap Broekhuizen
Jakub Mitoraj
Jan Balster
Janne Vanhala
Jason R. Coombs
Expand Down
1 change: 1 addition & 0 deletions changelog/6469.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
User can set ``junit_logging`` to one of ``no|log|system-out|system-err|out-err|all`` in order to put selected output in xml file.
2 changes: 1 addition & 1 deletion doc/en/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1166,7 +1166,7 @@ passed multiple times. The expected format is ``name=value``. For example::
.. versionadded:: 3.5

Configures if stdout/stderr should be written to the JUnit XML file. Valid values are
``system-out``, ``system-err``, and ``no`` (the default).
``log``, ``out-err``, ``all``, ``system-out``, ``system-err``, and ``no`` (the default).

.. code-block:: ini

Expand Down
71 changes: 24 additions & 47 deletions src/_pytest/junitxml.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,51 +167,28 @@ def write_captured_output(self, report):
content_out = report.capstdout
content_log = report.caplog
content_err = report.capstderr

if content_log or content_out:
if content_log and self.xml.logging == "system-out":
if content_out:
# syncing stdout and the log-output is not done yet. It's
# probably not worth the effort. Therefore, first the captured
# stdout is shown and then the captured logs.
content = "\n".join(
[
" Captured Stdout ".center(80, "-"),
content_out,
"",
" Captured Log ".center(80, "-"),
content_log,
]
)
else:
content = content_log
else:
content = content_out

if content:
tag = getattr(Junit, "system-out")
self.append(tag(bin_xml_escape(content)))

if content_log or content_err:
if content_log and self.xml.logging == "system-err":
if content_err:
content = "\n".join(
[
" Captured Stderr ".center(80, "-"),
content_err,
"",
" Captured Log ".center(80, "-"),
content_log,
]
)
else:
content = content_log
else:
content = content_err

if content:
tag = getattr(Junit, "system-err")
self.append(tag(bin_xml_escape(content)))
if self.xml.logging == "no":
return
content_all = ""
if self.xml.logging in ["log", "all"]:
content_all = self._prepare_content(content_log, " Captured Log ")
if self.xml.logging in ["system-out", "out-err", "all"]:
content_all += self._prepare_content(content_out, " Captured Out ")
self._write_content(report, content_all, "system-out")
content_all = ""
if self.xml.logging in ["system-err", "out-err", "all"]:
content_all += self._prepare_content(content_err, " Captured Err ")
self._write_content(report, content_all, "system-err")
content_all = ""
if content_all:
self._write_content(report, content_all, "system-out")

def _prepare_content(self, content, header):
return "\n".join([header.center(80, "-"), content, ""])

def _write_content(self, report, content, jheader):
tag = getattr(Junit, jheader)
self.append(tag(bin_xml_escape(content)))

def append_pass(self, report):
self.add_stats("passed")
Expand Down Expand Up @@ -408,9 +385,9 @@ def pytest_addoption(parser):
parser.addini(
"junit_logging",
"Write captured log messages to JUnit report: "
"one of no|system-out|system-err",
"one of no|log|system-out|system-err|out-err|all",
default="no",
) # choices=['no', 'stdout', 'stderr'])
)
parser.addini(
"junit_log_passing_tests",
"Capture log information for passing tests to JUnit report: ",
Expand Down
11 changes: 7 additions & 4 deletions testing/acceptance_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1297,7 +1297,11 @@ def test_simple():
"""
)
result = testdir.runpytest_subprocess(
testpath, "--capture=tee-sys", "--junitxml=output.xml"
testpath,
"--capture=tee-sys",
"--junitxml=output.xml",
"-o",
"junit_logging=all",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, the test was actually buggy: junit_logging by default is no, so it should not be writing stdout contents on the xml file. 👍

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, right.

)

# ensure stdout/stderr were 'live printed'
Expand All @@ -1307,6 +1311,5 @@ def test_simple():
# now ensure the output is in the junitxml
with open(os.path.join(testdir.tmpdir.strpath, "output.xml"), "r") as f:
fullXml = f.read()

assert "<system-out>@this is stdout@\n</system-out>" in fullXml
assert "<system-err>@this is stderr@\n</system-err>" in fullXml
assert "@this is stdout@\n" in fullXml
assert "@this is stderr@\n" in fullXml