pytest-dev/pytest · error · ValueError

Pytest terminal summary report not found

Error message

Pytest terminal summary report not found

What it means

Raised by RunResult.parse_summary_nouns when it scans the output lines in reverse looking for a line matching the session-duration regex (rex_session_duration) and finds none. Without that summary line it cannot extract the passed/failed/skipped counts, so assert_outcomes cannot proceed. This means the pytest run did not emit its normal terminal summary.

Source

Thrown at src/_pytest/pytester.py:585

        return self.parse_summary_nouns(self.outlines)

    @classmethod
    def parse_summary_nouns(cls, lines) -> dict[str, int]:
        """Extract the nouns from a pytest terminal summary line.

        It always returns the plural noun for consistency::

            ======= 1 failed, 1 passed, 1 warning, 1 error in 0.13s ====

        Will return ``{"failed": 1, "passed": 1, "warnings": 1, "errors": 1}``.
        """
        for line in reversed(lines):
            if rex_session_duration.search(line):
                outcomes = rex_outcome.findall(line)
                ret = {noun: int(count) for (count, noun) in outcomes}
                break
        else:
            raise ValueError("Pytest terminal summary report not found")

        to_plural = {
            "warning": "warnings",
            "error": "errors",
        }
        return {to_plural.get(k, k): v for k, v in ret.items()}

    def assert_outcomes(
        self,
        passed: int = 0,
        skipped: int = 0,
        failed: int = 0,
        errors: int = 0,
        xpassed: int = 0,
        xfailed: int = 0,
        warnings: int | None = None,
        deselected: int | None = None,
    ) -> None:

View on GitHub (pinned to 98b357f69e)

Solutions

  1. Print/inspect result.stdout lines to see where the run stopped before the summary.
  2. Ensure the terminal reporter plugin is enabled (avoid -p no:terminal).
  3. Increase subprocess timeout if the run was killed mid-execution.
  4. Re-run with -v / default options so the standard summary line is emitted.

Example fix

// before
result = pytester.runpytest_subprocess("-p", "no:terminal")
result.assert_outcomes(passed=1)  # no summary line exists
// after
result = pytester.runpytest_subprocess()
result.assert_outcomes(passed=1)
Defensive patterns

Strategy: validation

Validate before calling

import re
summary_present = any(re.search(r"in \d\.\d+s", line) for line in result.stdout.lines)
if not summary_present:
    print(result.stdout.str())
    raise AssertionError("no summary line; run likely crashed")
result.assert_outcomes(passed=1)

Try / catch

try:
    result.assert_outcomes(passed=1)
except ValueError:
    # dump output for diagnosis
    print(result.stdout.str())
    raise

Prevention

When it happens

Trigger: Calling result.assert_outcomes() on a RunResult whose captured stdout lacks the trailing '===== N passed in X.XXs =====' summary line, because the run was killed, crashed, used a non-default reporter (e.g. -p no:terminal), or the output was truncated.

Common situations: A pytest subprocess that segfaulted or was killed by a timeout; running with '-q' plus a plugin that suppresses the summary; an internal error during session teardown; capturing only stderr instead of stdout; pexpect/spawn runs whose output was not flushed before assertion.

Related errors


AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04). Data as JSON: /data/errors/9dd040c5d7725072.json. Report an issue: GitHub.