From 10f84e1889a18758824b08d2d60dfbd1fe5ca2a3 Mon Sep 17 00:00:00 2001 From: Kenny Y <24802984+kenny-y-dev@users.noreply.github.com> Date: Sun, 15 Dec 2024 09:41:27 -0500 Subject: [PATCH] Add --force-short-summary option and extend sequence printing with -vv --- changelog/12713.feature.rst | 5 ++++ src/_pytest/assertion/rewrite.py | 3 +++ src/_pytest/terminal.py | 11 +++++++- testing/test_terminal.py | 45 ++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 changelog/12713.feature.rst diff --git a/changelog/12713.feature.rst b/changelog/12713.feature.rst new file mode 100644 index 00000000000..b4e9270bcc1 --- /dev/null +++ b/changelog/12713.feature.rst @@ -0,0 +1,5 @@ +Add `--force-short-summary` option to force condensed summary output regardless of verbosity level + +Adds ability to still see condensed summary output of failures for quick reference in log files from job outputs. Especially useful if non-condensed output is very verbose. + +Also includes full fix for :issue:`11777` where sequences were still being shortened even with `-vv` verbosity. diff --git a/src/_pytest/assertion/rewrite.py b/src/_pytest/assertion/rewrite.py index 41e3d271396..2e606d1903a 100644 --- a/src/_pytest/assertion/rewrite.py +++ b/src/_pytest/assertion/rewrite.py @@ -28,6 +28,7 @@ from _pytest._io.saferepr import DEFAULT_REPR_MAX_SIZE from _pytest._io.saferepr import saferepr +from _pytest._io.saferepr import saferepr_unlimited from _pytest._version import version from _pytest.assertion import util from _pytest.config import Config @@ -433,6 +434,8 @@ def _saferepr(obj: object) -> str: return obj.__name__ maxsize = _get_maxsize_for_saferepr(util._config) + if not maxsize: + return saferepr_unlimited(obj).replace("\n", "\\n") return saferepr(obj, maxsize=maxsize).replace("\n", "\\n") diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index 348a78af9f5..f1373dc658c 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -161,6 +161,13 @@ def pytest_addoption(parser: Parser) -> None: default=True, help="Do not fold skipped tests in short summary.", ) + group._addoption( + "--force-short-summary", + action="store_true", + dest="force_short_summary", + default=False, + help="Force condensed summary output regardless of verbosity level.", + ) group._addoption( "-q", "--quiet", @@ -1467,7 +1474,9 @@ def _get_line_with_reprcrash_message( except AttributeError: pass else: - if running_on_ci() or config.option.verbose >= 2: + if ( + running_on_ci() or config.option.verbose >= 2 + ) and not config.option.force_short_summary: msg = f" - {msg}" else: available_width = tw.fullwidth - line_width diff --git a/testing/test_terminal.py b/testing/test_terminal.py index 6fa04be28b1..a572becb9bc 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -2520,6 +2520,51 @@ def test(): ) +def test_full_sequence_print_with_vv( + monkeypatch: MonkeyPatch, pytester: Pytester +) -> None: + monkeypatch.setattr(_pytest.terminal, "running_on_ci", lambda: False) + + pytester.makepyfile( + """ + def test_len_list(): + l = list(range(10)) + assert len(l) == 9 + + def test_len_dict(): + d = dict(zip(range(10), range(10))) + assert len(d) == 9 + """ + ) + + result = pytester.runpytest("-vv") + assert result.ret == 1 + result.stdout.fnmatch_lines( + [ + "*short test summary info*", + f"*{list(range(10))}*", + f"*{dict(zip(range(10), range(10)))}*", + ] + ) + + +def test_force_short_summary(monkeypatch: MonkeyPatch, pytester: Pytester) -> None: + monkeypatch.setattr(_pytest.terminal, "running_on_ci", lambda: False) + + pytester.makepyfile( + """ + def test(): + assert "a\\n" * 10 == "" + """ + ) + + result = pytester.runpytest("-vv", "--force-short-summary") + assert result.ret == 1 + result.stdout.fnmatch_lines( + ["*short test summary info*", "*AssertionError: assert 'a\\na\\na\\na..."] + ) + + @pytest.mark.parametrize( "seconds, expected", [