Skip to content
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
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Alejandro Villate
Alessio Izzo
Alex Jones
Alex Lambson
Alex Chen
Alexander Johnson
Alexander King
Alexei Kozlenok
Expand Down
4 changes: 4 additions & 0 deletions changelog/14724.improvement.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
``--no-summary`` now only applies directly to pytest's own summary.

The flag no longer skips the ``pytest_terminal_summary`` hook, so third-party
plugins (for example coverage) can still write their terminal summaries.
28 changes: 18 additions & 10 deletions src/_pytest/terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -968,7 +968,10 @@ def pytest_sessionfinish(
ExitCode.NO_TESTS_COLLECTED,
ExitCode.MAX_WARNINGS_ERROR,
)
if exitstatus in summary_exit_codes and not self.no_summary:
# Always invoke pytest_terminal_summary so third-party plugins can report
# (e.g. coverage). --no-summary only suppresses TerminalReporter's own
# built-in summary sections; see TerminalReporter.pytest_terminal_summary.
if exitstatus in summary_exit_codes:
self.config.hook.pytest_terminal_summary(
terminalreporter=self, exitstatus=exitstatus, config=self.config
)
Expand All @@ -995,18 +998,23 @@ def pytest_sessionfinish(

@hookimpl(wrapper=True)
def pytest_terminal_summary(self) -> Generator[None]:
self.summary_errors()
self.summary_failures()
self.summary_xfailures()
self.summary_warnings()
self.summary_passes()
self.summary_xpasses()
# With --no-summary, still yield so other plugins run their terminal
# summaries, but skip pytest's own FAILURES/ERRORS/... sections.
show_summary = not self.no_summary
if show_summary:
self.summary_errors()
self.summary_failures()
self.summary_xfailures()
self.summary_warnings()
self.summary_passes()
self.summary_xpasses()
try:
return (yield)
finally:
self.short_test_summary()
# Display any extra warnings from teardown here (if any).
self.summary_warnings()
if show_summary:
self.short_test_summary()
# Display any extra warnings from teardown here (if any).
self.summary_warnings()

def pytest_keyboard_interrupt(self, excinfo: ExceptionInfo[BaseException]) -> None:
self._keyboardinterrupt_memo = excinfo.getrepr(funcargs=True)
Expand Down
15 changes: 15 additions & 0 deletions testing/test_terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,21 @@ def test_no_summary():
result = pytester.runpytest(p1, "--no-summary")
result.stdout.no_fnmatch_line("*= FAILURES =*")

def test_no_summary_still_runs_terminal_summary_hook(
self, pytester: Pytester
) -> None:
"""--no-summary must not skip pytest_terminal_summary for plugins (#14724)."""
pytester.makeconftest(
"""
def pytest_terminal_summary(terminalreporter, exitstatus, config):
terminalreporter.write_line("PLUGIN_TERMINAL_SUMMARY_RAN")
"""
)
p1 = pytester.makepyfile("def test_ok(): assert True")
result = pytester.runpytest(p1, "--no-summary")
result.stdout.fnmatch_lines(["PLUGIN_TERMINAL_SUMMARY_RAN"])
result.stdout.no_fnmatch_line("*= FAILURES =*")

def test_showlocals(self, pytester: Pytester) -> None:
p1 = pytester.makepyfile(
"""
Expand Down