pytest-dev/pytest · error · ValueError

Pytest terminal summary report not found

Error message

Pytest terminal summary report not found

What it means

Thrown by RunResult.parse_summary_nouns() when scanning captured stdout lines in reverse finds no line matching the pytest session-duration regex (rex_session_duration). This means the terminal summary line pytest normally prints ('=== N passed in Xs ===') is absent from the captured output.

Solutions

  1. Inspect result.stdout.str() to see what was actually captured and why the summary line is missing.
  2. Check the RunResult.ret exit code for a crash (e.g. ExitCode.INTERNAL_ERROR).
  3. Ensure no -p no:terminal plugin disabled the terminal reporter.
  4. Increase subprocess timeout if the run was cut short.

Example fix

// before
result = pytester.runpytest_subprocess("-q")
result.assert_outcomes(passed=1)
// after
result = pytester.runpytest_subprocess("-q")
print(result.stdout.str())
assert result.ret == 0
result.assert_outcomes(passed=1)
Defensive patterns

Strategy: validation

Validate before calling

result = pytester.runpytest_subprocess('-q')
out = result.stdout.str()
import re
if not re.search(r'===+ .* in ', out):
    pytest.fail(f"no summary line in output:\n{out}")
result.assert_outcomes(passed=1)

Prevention

When it happens

Trigger: Calling result.parseoutcomes() or result.assert_outcomes() on a RunResult whose stdout was truncated, redirected away from capture, or where pytest crashed before printing the summary line; running pytest with flags that suppress the summary (e.g. -q with custom conftest intercepting terminal).

Common situations: Pytest crashed during session finish; a plugin's pytest_terminal_summary hook raised; capture was disabled or output went to stderr only; the subprocess was killed by timeout before the summary printed.

Related errors


AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11). Data as JSON: /api/errors/9dd040c5d7725072. Report an issue: GitHub.

Appendix: 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 0d6fbdeffa)