diff --git a/_pytest/debugging.py b/_pytest/debugging.py index d74cbe186..fada117e5 100644 --- a/_pytest/debugging.py +++ b/_pytest/debugging.py @@ -87,20 +87,16 @@ def _enter_pdb(node, excinfo, rep): tw = node.config.pluginmanager.getplugin("terminalreporter")._tw tw.line() - captured_stdout = rep.capstdout - if len(captured_stdout) > 0: - tw.sep(">", "captured stdout") - tw.line(captured_stdout) + showcapture = node.config.option.showcapture - captured_stderr = rep.capstderr - if len(captured_stderr) > 0: - tw.sep(">", "captured stderr") - tw.line(captured_stderr) - - captured_logs = rep.caplog - if len(captured_logs) > 0: - tw.sep(">", "captured logs") - tw.line(captured_logs) + for sectionname, content in (('stdout', rep.capstdout), + ('stderr', rep.capstderr), + ('log', rep.caplog)): + if showcapture in (sectionname, 'all') and content: + tw.sep(">", "captured " + sectionname) + if content[-1:] == "\n": + content = content[:-1] + tw.line(content) tw.sep(">", "traceback") rep.toterminal(tw) diff --git a/_pytest/terminal.py b/_pytest/terminal.py index 69d4ab8ad..55a632b22 100644 --- a/_pytest/terminal.py +++ b/_pytest/terminal.py @@ -44,9 +44,9 @@ def pytest_addoption(parser): help="traceback print mode (auto/long/short/line/native/no).") group._addoption('--show-capture', action="store", dest="showcapture", - choices=['no', 'stdout', 'stderr', 'both'], default='both', - help="Controls how captured stdout/stderr is shown on failed tests. " - "Default is 'both'.") + choices=['no', 'stdout', 'stderr', 'log', 'all'], default='all', + help="Controls how captured stdout/stderr/log is shown on failed tests. " + "Default is 'all'.") group._addoption('--fulltrace', '--full-trace', action="store_true", default=False, help="don't cut any tracebacks (default is to cut).") @@ -630,12 +630,12 @@ class TerminalReporter(object): def _outrep_summary(self, rep): rep.toterminal(self._tw) - if self.config.option.showcapture == 'no': + showcapture = self.config.option.showcapture + if showcapture == 'no': return for secname, content in rep.sections: - if self.config.option.showcapture != 'both': - if not (self.config.option.showcapture in secname): - continue + if showcapture != 'all' and showcapture not in secname: + continue self._tw.sep("-", secname) if content[-1:] == "\n": content = content[:-1] diff --git a/changelog/1478.feature b/changelog/1478.feature index de6bd3118..defc79b9b 100644 --- a/changelog/1478.feature +++ b/changelog/1478.feature @@ -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). \ No newline at end of file +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). diff --git a/testing/test_pdb.py b/testing/test_pdb.py index f6d03d6bb..fa3d86d31 100644 --- a/testing/test_pdb.py +++ b/testing/test_pdb.py @@ -187,16 +187,18 @@ class TestPDB(object): assert "captured stderr" not in output 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(""" def test_1(): import logging - logging.warn("get rekt") + logging.warn("get " + "rekt") assert False """) - child = testdir.spawn_pytest("--pdb %s" % p1) - child.expect("captured logs") - child.expect("get rekt") + child = testdir.spawn_pytest("--show-capture=%s --pdb %s" % (showcapture, p1)) + if showcapture in ('all', 'log'): + child.expect("captured log") + child.expect("get rekt") child.expect("(Pdb)") child.sendeof() rest = child.read().decode("utf8") diff --git a/testing/test_terminal.py b/testing/test_terminal.py index f23dffe25..b3ea01709 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -851,31 +851,47 @@ def pytest_report_header(config, startdir): def test_show_capture(self, testdir): testdir.makepyfile(""" import sys + import logging def test_one(): sys.stdout.write('!This is stdout!') sys.stderr.write('!This is stderr!') + logging.warning('!This is a warning log msg!') assert False, 'Something failed' """) result = testdir.runpytest("--tb=short") - result.stdout.fnmatch_lines(["!This is stdout!"]) - result.stdout.fnmatch_lines(["!This is stderr!"]) + result.stdout.fnmatch_lines(["!This is stdout!", + "!This is stderr!", + "*WARNING*!This is a warning log msg!"]) - result = testdir.runpytest("--show-capture=both", "--tb=short") - result.stdout.fnmatch_lines(["!This is stdout!"]) - result.stdout.fnmatch_lines(["!This is stderr!"]) + result = testdir.runpytest("--show-capture=all", "--tb=short") + result.stdout.fnmatch_lines(["!This is stdout!", + "!This is stderr!", + "*WARNING*!This is a warning log msg!"]) - result = testdir.runpytest("--show-capture=stdout", "--tb=short") - assert "!This is stderr!" not in result.stdout.str() - assert "!This is stdout!" in result.stdout.str() + stdout = testdir.runpytest( + "--show-capture=stdout", "--tb=short").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") - assert "!This is stdout!" not in result.stdout.str() - assert "!This is stderr!" in result.stdout.str() + stdout = testdir.runpytest( + "--show-capture=stderr", "--tb=short").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") - assert "!This is stdout!" not in result.stdout.str() - assert "!This is stderr!" not in result.stdout.str() + stdout = testdir.runpytest( + "--show-capture=log", "--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!" 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')")