diff --git a/AUTHORS b/AUTHORS index dee73514a..438be7598 100644 --- a/AUTHORS +++ b/AUTHORS @@ -56,6 +56,7 @@ Benjamin Peterson Bernard Pratz Bob Ippolito Brian Dorsey +Brian Larsen Brian Maissy Brian Okken Brianna Laugher diff --git a/changelog/10940.improvement.rst b/changelog/10940.improvement.rst new file mode 100644 index 000000000..f3e33cbc6 --- /dev/null +++ b/changelog/10940.improvement.rst @@ -0,0 +1,3 @@ +Improved verbose output (``-vv``) of ``skip`` and ``xfail`` reasons by performing text wrapping while leaving a clear margin for progress output. + +Added :func:`TerminalReporter.wrap_write() ` as a helper for that. diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index dfc0fa98e..b7793d398 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -8,6 +8,7 @@ import datetime import inspect import platform import sys +import textwrap import warnings from collections import Counter from functools import partial @@ -426,6 +427,28 @@ class TerminalReporter: self._tw.line() self.currentfspath = None + def wrap_write( + self, + content: str, + *, + flush: bool = False, + margin: int = 8, + line_sep: str = "\n", + **markup: bool, + ) -> None: + """Wrap message with margin for progress info.""" + width_of_current_line = self._tw.width_of_current_line + wrapped = line_sep.join( + textwrap.wrap( + " " * width_of_current_line + content, + width=self._screen_width - margin, + drop_whitespace=True, + replace_whitespace=False, + ), + ) + wrapped = wrapped[width_of_current_line:] + self._tw.write(wrapped, flush=flush, **markup) + def write(self, content: str, *, flush: bool = False, **markup: bool) -> None: self._tw.write(content, flush=flush, **markup) @@ -572,7 +595,7 @@ class TerminalReporter: formatted_reason = f" ({reason})" if reason and formatted_reason is not None: - self._tw.write(formatted_reason) + self.wrap_write(formatted_reason) if self._show_progress_info: self._write_progress_information_filling_space() else: diff --git a/testing/test_terminal.py b/testing/test_terminal.py index 97ce2cb56..c0acb6006 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -387,13 +387,13 @@ class TestTerminal: pytest.xfail("It's 🕙 o'clock") @pytest.mark.skip( - reason="cannot do foobar because baz is missing due to I don't know what" + reason="1 cannot do foobar because baz is missing due to I don't know what" ) def test_long_skip(): pass @pytest.mark.xfail( - reason="cannot do foobar because baz is missing due to I don't know what" + reason="2 cannot do foobar because baz is missing due to I don't know what" ) def test_long_xfail(): print(1 / 0) @@ -417,8 +417,8 @@ class TestTerminal: result.stdout.fnmatch_lines( common_output + [ - "test_verbose_skip_reason.py::test_long_skip SKIPPED (cannot *...) *", - "test_verbose_skip_reason.py::test_long_xfail XFAIL (cannot *...) *", + "test_verbose_skip_reason.py::test_long_skip SKIPPED (1 cannot *...) *", + "test_verbose_skip_reason.py::test_long_xfail XFAIL (2 cannot *...) *", ] ) @@ -428,12 +428,14 @@ class TestTerminal: + [ ( "test_verbose_skip_reason.py::test_long_skip SKIPPED" - " (cannot do foobar because baz is missing due to I don't know what) *" + " (1 cannot do foobar" ), + "because baz is missing due to I don't know what) *", ( "test_verbose_skip_reason.py::test_long_xfail XFAIL" - " (cannot do foobar because baz is missing due to I don't know what) *" + " (2 cannot do foobar" ), + "because baz is missing due to I don't know what) *", ] )