Add captured-log support to --show-capture

Fixes: #3233
This commit is contained in:
Thomas Hisch 2018-02-18 12:42:25 +01:00
parent 069f32a8c4
commit 51ece00923
5 changed files with 54 additions and 40 deletions

View File

@ -87,20 +87,16 @@ def _enter_pdb(node, excinfo, rep):
tw = node.config.pluginmanager.getplugin("terminalreporter")._tw tw = node.config.pluginmanager.getplugin("terminalreporter")._tw
tw.line() tw.line()
captured_stdout = rep.capstdout showcapture = node.config.option.showcapture
if len(captured_stdout) > 0:
tw.sep(">", "captured stdout")
tw.line(captured_stdout)
captured_stderr = rep.capstderr for sectionname, content in (('stdout', rep.capstdout),
if len(captured_stderr) > 0: ('stderr', rep.capstderr),
tw.sep(">", "captured stderr") ('log', rep.caplog)):
tw.line(captured_stderr) if showcapture in (sectionname, 'all') and content:
tw.sep(">", "captured " + sectionname)
captured_logs = rep.caplog if content[-1:] == "\n":
if len(captured_logs) > 0: content = content[:-1]
tw.sep(">", "captured logs") tw.line(content)
tw.line(captured_logs)
tw.sep(">", "traceback") tw.sep(">", "traceback")
rep.toterminal(tw) rep.toterminal(tw)

View File

@ -44,9 +44,9 @@ def pytest_addoption(parser):
help="traceback print mode (auto/long/short/line/native/no).") help="traceback print mode (auto/long/short/line/native/no).")
group._addoption('--show-capture', group._addoption('--show-capture',
action="store", dest="showcapture", action="store", dest="showcapture",
choices=['no', 'stdout', 'stderr', 'both'], default='both', choices=['no', 'stdout', 'stderr', 'log', 'all'], default='all',
help="Controls how captured stdout/stderr is shown on failed tests. " help="Controls how captured stdout/stderr/log is shown on failed tests. "
"Default is 'both'.") "Default is 'all'.")
group._addoption('--fulltrace', '--full-trace', group._addoption('--fulltrace', '--full-trace',
action="store_true", default=False, action="store_true", default=False,
help="don't cut any tracebacks (default is to cut).") help="don't cut any tracebacks (default is to cut).")
@ -630,11 +630,11 @@ class TerminalReporter(object):
def _outrep_summary(self, rep): def _outrep_summary(self, rep):
rep.toterminal(self._tw) rep.toterminal(self._tw)
if self.config.option.showcapture == 'no': showcapture = self.config.option.showcapture
if showcapture == 'no':
return return
for secname, content in rep.sections: for secname, content in rep.sections:
if self.config.option.showcapture != 'both': if showcapture != 'all' and showcapture not in secname:
if not (self.config.option.showcapture in secname):
continue continue
self._tw.sep("-", secname) self._tw.sep("-", secname)
if content[-1:] == "\n": if content[-1:] == "\n":

View File

@ -1 +1 @@
New ``--show-capture`` command-line option that allows to specify how to display captured output when tests fail: ``no``, ``stdout``, ``stderr`` or ``both`` (the default). New ``--show-capture`` command-line option that allows to specify how to display captured output when tests fail: ``no``, ``stdout``, ``stderr``, ``log`` or ``all`` (the default).

View File

@ -187,15 +187,17 @@ class TestPDB(object):
assert "captured stderr" not in output assert "captured stderr" not in output
self.flush(child) self.flush(child)
def test_pdb_print_captured_logs(self, testdir): @pytest.mark.parametrize('showcapture', ['all', 'no', 'log'])
def test_pdb_print_captured_logs(self, testdir, showcapture):
p1 = testdir.makepyfile(""" p1 = testdir.makepyfile("""
def test_1(): def test_1():
import logging import logging
logging.warn("get rekt") logging.warn("get " + "rekt")
assert False assert False
""") """)
child = testdir.spawn_pytest("--pdb %s" % p1) child = testdir.spawn_pytest("--show-capture=%s --pdb %s" % (showcapture, p1))
child.expect("captured logs") if showcapture in ('all', 'log'):
child.expect("captured log")
child.expect("get rekt") child.expect("get rekt")
child.expect("(Pdb)") child.expect("(Pdb)")
child.sendeof() child.sendeof()

View File

@ -851,31 +851,47 @@ def pytest_report_header(config, startdir):
def test_show_capture(self, testdir): def test_show_capture(self, testdir):
testdir.makepyfile(""" testdir.makepyfile("""
import sys import sys
import logging
def test_one(): def test_one():
sys.stdout.write('!This is stdout!') sys.stdout.write('!This is stdout!')
sys.stderr.write('!This is stderr!') sys.stderr.write('!This is stderr!')
logging.warning('!This is a warning log msg!')
assert False, 'Something failed' assert False, 'Something failed'
""") """)
result = testdir.runpytest("--tb=short") result = testdir.runpytest("--tb=short")
result.stdout.fnmatch_lines(["!This is stdout!"]) result.stdout.fnmatch_lines(["!This is stdout!",
result.stdout.fnmatch_lines(["!This is stderr!"]) "!This is stderr!",
"*WARNING*!This is a warning log msg!"])
result = testdir.runpytest("--show-capture=both", "--tb=short") result = testdir.runpytest("--show-capture=all", "--tb=short")
result.stdout.fnmatch_lines(["!This is stdout!"]) result.stdout.fnmatch_lines(["!This is stdout!",
result.stdout.fnmatch_lines(["!This is stderr!"]) "!This is stderr!",
"*WARNING*!This is a warning log msg!"])
result = testdir.runpytest("--show-capture=stdout", "--tb=short") stdout = testdir.runpytest(
assert "!This is stderr!" not in result.stdout.str() "--show-capture=stdout", "--tb=short").stdout.str()
assert "!This is stdout!" in result.stdout.str() assert "!This is stderr!" not in stdout
assert "!This is stdout!" in stdout
assert "!This is a warning log msg!" not in stdout
result = testdir.runpytest("--show-capture=stderr", "--tb=short") stdout = testdir.runpytest(
assert "!This is stdout!" not in result.stdout.str() "--show-capture=stderr", "--tb=short").stdout.str()
assert "!This is stderr!" in result.stdout.str() assert "!This is stdout!" not in stdout
assert "!This is stderr!" in stdout
assert "!This is a warning log msg!" not in stdout
result = testdir.runpytest("--show-capture=no", "--tb=short") stdout = testdir.runpytest(
assert "!This is stdout!" not in result.stdout.str() "--show-capture=log", "--tb=short").stdout.str()
assert "!This is stderr!" not in result.stdout.str() assert "!This is stdout!" not in stdout
assert "!This is stderr!" not in stdout
assert "!This is a warning log msg!" in stdout
stdout = testdir.runpytest(
"--show-capture=no", "--tb=short").stdout.str()
assert "!This is stdout!" not in stdout
assert "!This is stderr!" not in stdout
assert "!This is a warning log msg!" not in stdout
@pytest.mark.xfail("not hasattr(os, 'dup')") @pytest.mark.xfail("not hasattr(os, 'dup')")