From a9e8ead563bbaeb27952f0ff3d156c0d5a8cf373 Mon Sep 17 00:00:00 2001 From: Brian Okken <1568356+okken@users.noreply.github.com> Date: Sun, 28 Apr 2024 12:56:28 -0700 Subject: [PATCH] Change default, add more tests, add changelog entry --- changelog/12231.feature.rst | 16 +++++++++++++++ src/_pytest/terminal.py | 6 +++--- testing/test_terminal.py | 41 +++++++++++++++++++++++++++++-------- 3 files changed, 52 insertions(+), 11 deletions(-) create mode 100644 changelog/12231.feature.rst diff --git a/changelog/12231.feature.rst b/changelog/12231.feature.rst new file mode 100644 index 000000000..6369c92f7 --- /dev/null +++ b/changelog/12231.feature.rst @@ -0,0 +1,16 @@ +Add `--xfail-tb` flag, which acts a lot like `--tb`, but controls the traceback output for XFAIL results. + +* The `--xfail-tb` flag takes one argument, `auto|long|short|line|native|no`, and defaults to `no`. +* To turn on xfail tracebacks, pass in `-rx` or `-ra` along with `--xfail-tb=short` (or any of `auto`, `long`, `short`, `line`, or `native`). + +The `--tb` flag, that controls normal test failure tracebacks, defaults to `auto`. +This change really only separates the traceback behavior of normal vs xfail failures. + +Some history: + +* This is a behavior break, but brings default behavior back to pre-8.0.0 behavior. +* With this change, default `-rx`/ `-ra` behavior is identical to pre-8.0 with respect to xfail tracebacks. +* With pytest 8.0, `-rx` or `-ra` would not only turn on summary reports for xfail, but also report the tracebacks for xfail results. +* This caused issues with some projects that utilize xfail, but don't want to see all of the xfail tracebacks. + + diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index 441aa1c2b..bd12e56cf 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -221,9 +221,9 @@ def pytest_addoption(parser: Parser) -> None: metavar="style", action="store", dest="xfail_tbstyle", - default="auto", + default="no", choices=["auto", "long", "short", "no", "line", "native"], - help="Traceback print mode for xfail(auto/long/short/line/native/no)", + help="Traceback print mode for xfail (auto/long/short/line/native/no)", ) group._addoption( "--show-capture", @@ -1091,7 +1091,7 @@ class TerminalReporter: which_reports: str, sep_title: str, needed_opt: Optional[str] = None, - style=None, + style: Optional[str] = None, ) -> None: if style is None: style = self.config.option.tbstyle diff --git a/testing/test_terminal.py b/testing/test_terminal.py index 60c49c644..4957c0e02 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -2909,7 +2909,7 @@ def test_summary_xfail_reason(pytester: Pytester) -> None: assert result.stdout.lines.count(expect2) == 1 -def test_summary_xfail_tb(pytester: Pytester) -> None: +def test_xfail_tb_default(pytester: Pytester) -> None: pytester.makepyfile( """ import pytest @@ -2920,19 +2920,44 @@ def test_summary_xfail_tb(pytester: Pytester) -> None: assert a == b """ ) + # defaults to "no", so this is the same as `runpytest("-rx", "--xfail-tb=no")` result = pytester.runpytest("-rx") + # Don't show traceback + result.stdout.no_fnmatch_line("*= XFAILURES =*") + result.stdout.no_fnmatch_line("*test_xfail_tb_line.py:6: assert 1 == 2") + # still print summary + result.stdout.fnmatch_lines( + [ + "*= short test summary info =*", + "XFAIL test_xfail_tb_default.py::test_xfail", + "*= 1 xfailed in * =*", + ] + ) + + +def test_xfail_tb_short(pytester: Pytester) -> None: + pytester.makepyfile( + """ + import pytest + + @pytest.mark.xfail + def test_xfail(): + a, b = 1, 2 + assert a == b + """ + ) + result = pytester.runpytest("-rx", "--xfail-tb=short") result.stdout.fnmatch_lines( [ "*= XFAILURES =*", "*_ test_xfail _*", - "* @pytest.mark.xfail*", - "* def test_xfail():*", - "* a, b = 1, 2*", - "> *assert a == b*", - "E *assert 1 == 2*", - "test_summary_xfail_tb.py:6: AssertionError*", + "*@pytest.mark.xfail*", + "*def test_xfail():*", + "* a, b = 1, 2*", + "*> *assert a == b*", + "*E *assert 1 == 2*", "*= short test summary info =*", - "XFAIL test_summary_xfail_tb.py::test_xfail", + "XFAIL test_xfail_tb_short.py::test_xfail", "*= 1 xfailed in * =*", ] )