Python test failures — FAILED test.py::test / AssertionError
Log signatures
FAILED tests/test_x.py::test_name AssertionError ModuleNotFoundError E assert 3 == 4
What’s happening
"FAILED path/to/test.py::test_name" is pytest's failure line — the :: makes it grep-able and gives you the exact node to rerun. The crucial split is AssertionError vs ModuleNotFoundError: an assertion means behavior drifted (a real test failure); ModuleNotFoundError means the test environment is broken — a missing dependency, a packaging/layout problem (src/ layout without installing the package), or a test importing something that was renamed. A wall of failures that are all ModuleNotFoundError for the same module is one environment bug, not N test bugs.
Fix playbook
- 1Copy the first FAILED node and rerun exactly that: python -m pytest "tests/test_x.py::test_name" -x -q. Seconds, not minutes.
- 2ModuleNotFoundError: fix the environment — is the package installed (pip install -e .)? Is the dependency in the right extras group that CI installs? Don't touch test logic.
- 3AssertionError: read pytest's diff (it prints both sides). Decide which side is right: the code regressed, or the test encodes outdated expectations. Fix exactly one of them.
- 4Passes locally, fails in CI: compare Python versions, then look for test ordering/state leakage — run the failing test alone, then the full suite with -p no:randomly (or with a fixed seed) to confirm an inter-test dependency.
- 5Rerun the focused node, then the file, then the suite. Escalate scope only on green.
Prevention
- Run tests against the installed package (src layout + pip install -e .) so CI and local imports resolve identically.
Triage every red build, not just this one.
This page is one of 31 failure classes the open-source patchrail CLI matches from a raw log — locally, with secrets redacted first. If a log stumps it, open an issue; if it saves you a debugging morning, a star helps other maintainers find it.
pipx install patchrail