Skip to content

feat: add --fold-skipped=yes|no cli option #12567

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@
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 @@
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 @@
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 @@
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", [])

Check warning on line 1264 in src/_pytest/terminal.py

View check run for this annotation

Codecov / codecov/patch

src/_pytest/terminal.py#L1264

Added line #L1264 was not covered by tests

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)

Check warning on line 1269 in src/_pytest/terminal.py

View check run for this annotation

Codecov / codecov/patch

src/_pytest/terminal.py#L1267-L1269

Added lines #L1267 - L1269 were not covered by tests

verbose_word, verbose_markup = rep._get_verbose_word_with_markup(

Check warning on line 1271 in src/_pytest/terminal.py

View check run for this annotation

Codecov / codecov/patch

src/_pytest/terminal.py#L1271

Added line #L1271 was not covered by tests
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]

Check warning on line 1277 in src/_pytest/terminal.py

View check run for this annotation

Codecov / codecov/patch

src/_pytest/terminal.py#L1274-L1277

Added lines #L1274 - L1277 were not covered by tests
if reason:
line += " - " + str(reason)
lines.append(line)

Check warning on line 1280 in src/_pytest/terminal.py

View check run for this annotation

Codecov / codecov/patch

src/_pytest/terminal.py#L1279-L1280

Added lines #L1279 - L1280 were not covered by tests

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

Check warning on line 1284 in src/_pytest/terminal.py

View check run for this annotation

Codecov / codecov/patch

src/_pytest/terminal.py#L1284

Added line #L1284 was not covered by tests
else:
show_skipped_unfolded(lines)

Check warning on line 1286 in src/_pytest/terminal.py

View check run for this annotation

Codecov / codecov/patch

src/_pytest/terminal.py#L1286

Added line #L1286 was not covered by tests

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
Loading