Skip to content

Commit

Permalink
Add --no-fold-skipped cli option (#12567)
Browse files Browse the repository at this point in the history
This allows users to disable the default behavior of folding skipped tests in the short summary.

Fix #9876

Signed-off-by: Pavel Březina <pbrezina@redhat.com>
  • Loading branch information
pbrezina authored Jul 5, 2024
1 parent e19ad1f commit cf5369d
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 1 deletion.
7 changes: 7 additions & 0 deletions changelog/12567.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Added ``--no-fold-skipped`` command line option

If this option is set, then skipped tests in short summary are no longer grouped
by reason but all tests are printed individually with correct nodeid in the same
way as other statuses.

-- by :user:`pbrezina`
5 changes: 5 additions & 0 deletions doc/en/how-to/output.rst
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,11 @@ captured output:
PASSED test_example.py::test_ok
== 1 failed, 1 passed, 1 skipped, 1 xfailed, 1 xpassed, 1 error in 0.12s ===
.. note::

By default, parametrized variants of skipped tests are grouped together if
they share the same skip reason. You can use ``--no-fold-skipped`` to print each skipped test separately.

Creating resultlog format files
--------------------------------------------------

Expand Down
35 changes: 34 additions & 1 deletion src/_pytest/terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,13 @@ def pytest_addoption(parser: Parser) -> None:
dest="no_summary",
help="Disable summary",
)
group._addoption(
"--no-fold-skipped",
action="store_false",
dest="fold_skipped",
default=True,
help="Do not fold skipped tests in short summary.",
)
group._addoption(
"-q",
"--quiet",
Expand Down Expand Up @@ -371,6 +378,7 @@ def __init__(self, config: Config, file: TextIO | None = None) -> None:
self._screen_width = self._tw.fullwidth
self.currentfspath: None | Path | str | int = None
self.reportchars = getreportopt(config)
self.foldskipped = config.option.fold_skipped
self.hasmarkup = self._tw.hasmarkup
self.isatty = file.isatty()
self._progress_nodeids_reported: set[str] = set()
Expand Down Expand Up @@ -1232,7 +1240,7 @@ def show_xpassed(lines: list[str]) -> None:
line += " - " + str(reason)
lines.append(line)

def show_skipped(lines: list[str]) -> None:
def show_skipped_folded(lines: list[str]) -> None:
skipped: list[CollectReport] = self.stats.get("skipped", [])
fskips = _folded_skips(self.startpath, skipped) if skipped else []
if not fskips:
Expand All @@ -1252,6 +1260,31 @@ def show_skipped(lines: list[str]) -> None:
else:
lines.append("%s [%d] %s: %s" % (markup_word, num, fspath, reason))

def show_skipped_unfolded(lines: list[str]) -> None:
skipped: list[CollectReport] = self.stats.get("skipped", [])

for rep in skipped:
assert rep.longrepr is not None
assert isinstance(rep.longrepr, tuple), (rep, rep.longrepr)
assert len(rep.longrepr) == 3, (rep, rep.longrepr)

verbose_word, verbose_markup = rep._get_verbose_word_with_markup(
self.config, {_color_for_type["warnings"]: True}
)
markup_word = self._tw.markup(verbose_word, **verbose_markup)
nodeid = _get_node_id_with_markup(self._tw, self.config, rep)
line = f"{markup_word} {nodeid}"
reason = rep.longrepr[2]
if reason:
line += " - " + str(reason)
lines.append(line)

def show_skipped(lines: list[str]) -> None:
if self.foldskipped:
show_skipped_folded(lines)
else:
show_skipped_unfolded(lines)

REPORTCHAR_ACTIONS: Mapping[str, Callable[[list[str]], None]] = {
"x": show_xfailed,
"X": show_xpassed,
Expand Down
38 changes: 38 additions & 0 deletions testing/test_terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,44 @@ def test():
result.stdout.fnmatch_lines([expected])
assert result.stdout.lines.count(expected) == 1

def test_summary_s_folded(self, pytester: Pytester) -> None:
"""Test that skipped tests are correctly folded"""
pytester.makepyfile(
"""
import pytest
@pytest.mark.parametrize("param", [True, False])
@pytest.mark.skip("Some reason")
def test(param):
pass
"""
)
result = pytester.runpytest("-rs")
expected = "SKIPPED [2] test_summary_s_folded.py:3: Some reason"
result.stdout.fnmatch_lines([expected])
assert result.stdout.lines.count(expected) == 1

def test_summary_s_unfolded(self, pytester: Pytester) -> None:
"""Test that skipped tests are not folded if --no-fold-skipped is set"""
pytester.makepyfile(
"""
import pytest
@pytest.mark.parametrize("param", [True, False])
@pytest.mark.skip("Some reason")
def test(param):
pass
"""
)
result = pytester.runpytest("-rs", "--no-fold-skipped")
expected = [
"SKIPPED test_summary_s_unfolded.py::test[True] - Skipped: Some reason",
"SKIPPED test_summary_s_unfolded.py::test[False] - Skipped: Some reason",
]
result.stdout.fnmatch_lines(expected)
assert result.stdout.lines.count(expected[0]) == 1
assert result.stdout.lines.count(expected[1]) == 1


@pytest.mark.parametrize(
("use_ci", "expected_message"),
Expand Down

0 comments on commit cf5369d

Please sign in to comment.