terminal: default to `fE` with `-r` (reportchars)

Adds handling of `N` to reset `reportchars`, which can be used to get
the old behavior (`-rN`), and also allows for an alternative to
`--disable-warnings` (https://github.com/pytest-dev/pytest/issues/5066),
since `w` was included by default (without `--disable-warnings`).

Fixes https://github.com/pytest-dev/pytest/issues/6454
This commit is contained in:
Daniel Hahler 2020-01-21 13:39:34 +01:00
parent 2e8f7ef31b
commit ddaa5d88ac
5 changed files with 71 additions and 34 deletions

View File

@ -0,0 +1 @@
`--disable-warnings` is honored with `-ra` and `-rA`.

View File

@ -0,0 +1 @@
Changed default for `-r` to `fE`, which displays failures and errors in the :ref:`short test summary <pytest.detailed_failed_tests_usage>`. `-rN` can be used to disable it (the old behavior).

View File

@ -169,11 +169,11 @@ option you make sure a trace is shown.
Detailed summary report Detailed summary report
----------------------- -----------------------
The ``-r`` flag can be used to display a "short test summary info" at the end of the test session, The ``-r`` flag can be used to display a "short test summary info" at the end of the test session,
making it easy in large test suites to get a clear picture of all failures, skips, xfails, etc. making it easy in large test suites to get a clear picture of all failures, skips, xfails, etc.
It defaults to ``fE`` to list failures and errors.
Example: Example:
.. code-block:: python .. code-block:: python
@ -261,8 +261,12 @@ Here is the full list of available characters that can be used:
- ``X`` - xpassed - ``X`` - xpassed
- ``p`` - passed - ``p`` - passed
- ``P`` - passed with output - ``P`` - passed with output
Special characters for (de)selection of groups:
- ``a`` - all except ``pP`` - ``a`` - all except ``pP``
- ``A`` - all - ``A`` - all
- ``N`` - none, this can be used to display nothing (since ``fE`` is the default)
More than one character can be used, so for example to only see failed and skipped tests, you can execute: More than one character can be used, so for example to only see failed and skipped tests, you can execute:

View File

@ -33,6 +33,8 @@ from _pytest.reports import TestReport
REPORT_COLLECTING_RESOLUTION = 0.5 REPORT_COLLECTING_RESOLUTION = 0.5
_REPORTCHARS_DEFAULT = "fE"
class MoreQuietAction(argparse.Action): class MoreQuietAction(argparse.Action):
""" """
@ -88,12 +90,13 @@ def pytest_addoption(parser):
"-r", "-r",
action="store", action="store",
dest="reportchars", dest="reportchars",
default="", default=_REPORTCHARS_DEFAULT,
metavar="chars", metavar="chars",
help="show extra test summary info as specified by chars: (f)ailed, " help="show extra test summary info as specified by chars: (f)ailed, "
"(E)rror, (s)kipped, (x)failed, (X)passed, " "(E)rror, (s)kipped, (x)failed, (X)passed, "
"(p)assed, (P)assed with output, (a)ll except passed (p/P), or (A)ll. " "(p)assed, (P)assed with output, (a)ll except passed (p/P), or (A)ll. "
"(w)arnings are enabled by default (see --disable-warnings).", "(w)arnings are enabled by default (see --disable-warnings), "
"'N' can be used to reset the list. (default: 'fE').",
) )
group._addoption( group._addoption(
"--disable-warnings", "--disable-warnings",
@ -166,24 +169,27 @@ def pytest_configure(config: Config) -> None:
def getreportopt(config: Config) -> str: def getreportopt(config: Config) -> str:
reportopts = ""
reportchars = config.option.reportchars reportchars = config.option.reportchars
if not config.option.disable_warnings and "w" not in reportchars:
reportchars += "w" old_aliases = {"F", "S"}
elif config.option.disable_warnings and "w" in reportchars: reportopts = ""
reportchars = reportchars.replace("w", "")
aliases = {"F", "S"}
for char in reportchars: for char in reportchars:
# handle old aliases if char in old_aliases:
if char in aliases:
char = char.lower() char = char.lower()
if char == "a": if char == "a":
reportopts = "sxXwEf" reportopts = "sxXEf"
elif char == "A": elif char == "A":
reportopts = "PpsxXwEf" reportopts = "PpsxXEf"
break elif char == "N":
reportopts = ""
elif char not in reportopts: elif char not in reportopts:
reportopts += char reportopts += char
if not config.option.disable_warnings and "w" not in reportopts:
reportopts = "w" + reportopts
elif config.option.disable_warnings and "w" in reportopts:
reportopts = reportopts.replace("w", "")
return reportopts return reportopts

View File

@ -813,9 +813,9 @@ class TestTerminalFunctional:
def test_fail_extra_reporting(testdir, monkeypatch): def test_fail_extra_reporting(testdir, monkeypatch):
monkeypatch.setenv("COLUMNS", "80") monkeypatch.setenv("COLUMNS", "80")
testdir.makepyfile("def test_this(): assert 0, 'this_failed' * 100") testdir.makepyfile("def test_this(): assert 0, 'this_failed' * 100")
result = testdir.runpytest() result = testdir.runpytest("-rN")
result.stdout.no_fnmatch_line("*short test summary*") result.stdout.no_fnmatch_line("*short test summary*")
result = testdir.runpytest("-rf") result = testdir.runpytest()
result.stdout.fnmatch_lines( result.stdout.fnmatch_lines(
[ [
"*test summary*", "*test summary*",
@ -984,37 +984,62 @@ def test_color_yes_collection_on_non_atty(testdir, verbose):
def test_getreportopt(): def test_getreportopt():
from _pytest.terminal import _REPORTCHARS_DEFAULT
class Config: class Config:
class Option: class Option:
reportchars = "" reportchars = _REPORTCHARS_DEFAULT
disable_warnings = True disable_warnings = False
option = Option() option = Option()
config = Config() config = Config()
assert _REPORTCHARS_DEFAULT == "fE"
# Default.
assert getreportopt(config) == "wfE"
config.option.reportchars = "sf" config.option.reportchars = "sf"
assert getreportopt(config) == "sf" assert getreportopt(config) == "wsf"
config.option.reportchars = "sfxw"
assert getreportopt(config) == "sfxw"
config.option.reportchars = "a"
assert getreportopt(config) == "wsxXEf"
config.option.reportchars = "N"
assert getreportopt(config) == "w"
config.option.reportchars = "NwfE"
assert getreportopt(config) == "wfE"
config.option.reportchars = "NfENx"
assert getreportopt(config) == "wx"
# Now with --disable-warnings.
config.option.disable_warnings = True
config.option.reportchars = "a"
assert getreportopt(config) == "sxXEf"
config.option.reportchars = "sfx"
assert getreportopt(config) == "sfx"
config.option.reportchars = "sfxw" config.option.reportchars = "sfxw"
assert getreportopt(config) == "sfx" assert getreportopt(config) == "sfx"
# Now with --disable-warnings.
config.option.disable_warnings = False
config.option.reportchars = "a" config.option.reportchars = "a"
assert getreportopt(config) == "sxXwEf" # NOTE: "w" included! assert getreportopt(config) == "sxXEf"
config.option.reportchars = "sfx"
assert getreportopt(config) == "sfxw"
config.option.reportchars = "sfxw"
assert getreportopt(config) == "sfxw"
config.option.reportchars = "a"
assert getreportopt(config) == "sxXwEf" # NOTE: "w" included!
config.option.reportchars = "A" config.option.reportchars = "A"
assert getreportopt(config) == "PpsxXwEf" assert getreportopt(config) == "PpsxXEf"
config.option.reportchars = "AN"
assert getreportopt(config) == ""
config.option.reportchars = "NwfE"
assert getreportopt(config) == "fE"
def test_terminalreporter_reportopt_addopts(testdir): def test_terminalreporter_reportopt_addopts(testdir):
@ -1131,7 +1156,7 @@ class TestGenericReporting:
) )
for tbopt in ["long", "short", "no"]: for tbopt in ["long", "short", "no"]:
print("testing --tb=%s..." % tbopt) print("testing --tb=%s..." % tbopt)
result = testdir.runpytest("--tb=%s" % tbopt) result = testdir.runpytest("-rN", "--tb=%s" % tbopt)
s = result.stdout.str() s = result.stdout.str()
if tbopt == "long": if tbopt == "long":
assert "print(6*7)" in s assert "print(6*7)" in s