From 2543dcd3bae3b523568ebf79a0db9841bf4735e0 Mon Sep 17 00:00:00 2001 From: Copilot <223556219+Copilot@users.noreply.github.com> Date: Tue, 27 Oct 2026 14:24:57 -0300 Subject: [PATCH] Add option to disable short summary truncation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- changelog/10264.feature.rst | 1 + doc/en/reference/reference.rst | 5 ++++ src/_pytest/terminal.py | 15 ++++++++-- testing/test_terminal.py | 54 +++++++++++++++++++++++++++++++++- 4 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 changelog/10264.feature.rst diff --git a/changelog/10264.feature.rst b/changelog/10264.feature.rst new file mode 100644 index 00000000000..b7d103bcc69 --- /dev/null +++ b/changelog/10264.feature.rst @@ -0,0 +1 @@ +Added the :option:`--no-truncate-summary` option to show complete first lines of messages in the short test summary. diff --git a/doc/en/reference/reference.rst b/doc/en/reference/reference.rst index 87abcc5f74d..d0db91f239b 100644 --- a/doc/en/reference/reference.rst +++ b/doc/en/reference/reference.rst @@ -3179,6 +3179,11 @@ Output and Reporting Force condensed summary output regardless of verbosity level. +.. option:: --no-truncate-summary + + Do not truncate messages in the short test summary, regardless of terminal width. + Only the first line of each message is displayed. + .. option:: -l, --showlocals Show locals in tracebacks (disabled by default). diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index 00ef7d3cddb..0e9cf2796d2 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -178,6 +178,12 @@ def pytest_addoption(parser: Parser) -> None: default=False, help="Force condensed summary output regardless of verbosity level.", ) + group.addoption( + "--no-truncate-summary", + action="store_true", + default=False, + help="Do not truncate messages in the short test summary.", + ) group._addoption( # private to use reserved lower-case short option "-q", "--quiet", @@ -1596,9 +1602,12 @@ def _get_line_with_reprcrash_message( except AttributeError: pass else: - if ( - running_on_ci() or config.option.verbose >= 2 - ) and not config.option.force_short_summary: + if config.option.force_short_summary: + available_width = tw.fullwidth - line_width + msg = _format_trimmed(" - {}", msg, available_width) + elif config.option.no_truncate_summary: + msg = " - " + msg.partition("\n")[0] + elif running_on_ci() or config.option.verbose >= 2: msg = f" - {msg}" else: available_width = tw.fullwidth - line_width diff --git a/testing/test_terminal.py b/testing/test_terminal.py index 21b0557a470..eeb051c01e0 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -2738,7 +2738,11 @@ def __init__(self, **kwargs): class config: def __init__(self): - self.option = Namespace(verbose=0) + self.option = Namespace( + verbose=0, + force_short_summary=False, + no_truncate_summary=False, + ) class rep: def _get_verbose_word_with_markup(self, *args): @@ -2886,6 +2890,54 @@ def test(): ) +@pytest.mark.parametrize( + ("args", "running_on_ci", "truncated"), + [ + ([], False, True), + (["--no-truncate-summary"], False, False), + (["--no-truncate-summary"], True, False), + (["-vv", "--force-short-summary"], False, True), + (["--no-truncate-summary", "-vv", "--force-short-summary"], False, True), + ], +) +def test_no_truncate_summary( + monkeypatch: MonkeyPatch, + pytester: Pytester, + args: list[str], + running_on_ci: bool, + truncated: bool, +) -> None: + monkeypatch.setattr(_pytest.terminal, "running_on_ci", lambda: running_on_ci) + monkeypatch.setenv("COLUMNS", "80") + pytester.makepyfile( + test_summary=""" + import pytest + + def test_fail(): + pytest.fail("A" * 100 + "\\nSECOND_LINE") + """ + ) + + result = pytester.runpytest(*args) + assert result.ret == 1 + + summary_index = next( + i + for i, line in enumerate(result.stdout.lines) + if "short test summary info" in line + ) + summary_line = next( + line + for line in result.stdout.lines[summary_index + 1 :] + if line.startswith("FAILED test_summary.py::test_fail ") + ) + assert "SECOND_LINE" not in summary_line + if truncated: + assert summary_line.endswith("...") + else: + assert "A" * 100 in summary_line + + @pytest.mark.parametrize( "seconds, expected", [