diff --git a/AUTHORS b/AUTHORS index 80b6d5157..232b2c7b2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -185,6 +185,7 @@ Ilya Konstantinov Ionuț Turturică Isaac Virshup Israel Fruchter +Itamar Hindi Itxaso Aizpurua Iwan Briquemont Jaap Broekhuizen @@ -371,6 +372,7 @@ Sanket Duthade Sankt Petersbug Saravanan Padmanaban Sean Malloy +Sebin (Eichel) Choi Segev Finer Serhii Mozghovyi Seth Junot diff --git a/changelog/11037.feature.rst b/changelog/11037.feature.rst new file mode 100644 index 000000000..434381e76 --- /dev/null +++ b/changelog/11037.feature.rst @@ -0,0 +1 @@ +Added stdio as option for --show-capture to have both stderr and stdout output together. diff --git a/src/_pytest/debugging.py b/src/_pytest/debugging.py index eacb2836d..bad6c3061 100644 --- a/src/_pytest/debugging.py +++ b/src/_pytest/debugging.py @@ -348,7 +348,13 @@ def _enter_pdb( ("stderr", rep.capstderr), ("log", rep.caplog), ): - if showcapture in (sectionname, "all") and content: + if ( + showcapture in (sectionname, "all") + or ( + showcapture == "stdio" + and ("stdout" in sectionname or "stderr" in sectionname) + ) + ) and content: tw.sep(">", "captured " + sectionname) if content[-1:] == "\n": content = content[:-1] diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index 2eef8d1f2..37f325ca2 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -227,9 +227,9 @@ def pytest_addoption(parser: Parser) -> None: "--show-capture", action="store", dest="showcapture", - choices=["no", "stdout", "stderr", "log", "all"], + choices=["no", "stdout", "stderr", "log", "stdio", "all"], default="all", - help="Controls how captured stdout/stderr/log is shown on failed tests. " + help="Controls how captured stdout/stderr/log is shown on failed tests. stdio displays both stdout and stderr. " "Default: all.", ) group._addoption( @@ -1084,7 +1084,14 @@ class TerminalReporter: if showcapture == "no": return for secname, content in rep.sections: - if showcapture != "all" and showcapture not in secname: + if ( + showcapture != "all" + and showcapture not in secname + and ( + showcapture != "stdio" + or ("stderr" not in secname and "stdout" not in secname) + ) + ): continue if "teardown" in secname: self._tw.sep("-", secname) @@ -1147,7 +1154,14 @@ class TerminalReporter: if showcapture == "no": return for secname, content in rep.sections: - if showcapture != "all" and showcapture not in secname: + if ( + showcapture != "all" + and showcapture not in secname + and ( + showcapture != "stdio" + or ("stderr" not in secname and "stdout" not in secname) + ) + ): continue self._tw.sep("-", secname) if content[-1:] == "\n": diff --git a/testing/test_terminal.py b/testing/test_terminal.py index ce9fdc50c..1be51693f 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -1611,6 +1611,11 @@ def pytest_report_header(config, start_path): assert "!This is stderr!" not in stdout assert "!This is a warning log msg!" in stdout + stdout = pytester.runpytest("--show-capture=stdio", "--tb=short").stdout.str() + assert "!This is stdout!" in stdout + assert "!This is stderr!" in stdout + assert "!This is a warning log msg!" not in stdout + stdout = pytester.runpytest("--show-capture=no", "--tb=short").stdout.str() assert "!This is stdout!" not in stdout assert "!This is stderr!" not in stdout @@ -1651,6 +1656,11 @@ def pytest_report_header(config, start_path): assert "!stderr!" not in result assert "!log!" in result + result = pytester.runpytest("--show-capture=stdio", "--tb=short").stdout.str() + assert "!stdout!" in result + assert "!stderr!" in result + assert "!log!" not in result + result = pytester.runpytest("--show-capture=no", "--tb=short").stdout.str() assert "!stdout!" not in result assert "!stderr!" not in result