A pytest plugin that explains failing tests like a senior engineer.
pytest-why turns common pytest failures into concise explanations and practical
next steps. It runs locally, adds no noise to normal test runs, and creates
shareable Markdown and HTML reports when you ask for them.
python -m pip install pytest-whyFor local development:
python -m pip install -e .[dev]Run pytest with one extra flag:
python -m pytest --whyWithout --why, the plugin does nothing and creates no report files.
Given:
def test_math():
assert 2 + 2 == 5Run:
pytest --whySample output:
================ pytest-why: failure explanations ================
Total failures: 1
Assertion mismatch: test_math.py::test_math (call)
Why: The code ran, but the observed value or state did not match what the test expected.
Hint: Compare the expected and actual values near the final assertion, then trace where they first diverge.
Reports: pytest-why-report.md, pytest-why-report.html
Each --why run writes:
pytest-why-report.mdfor pull requests, issue trackers, and terminalspytest-why-report.htmlfor a styled, standalone browser view
Both reports include the failing test, pytest phase, classification, duration, explanation, hint, and the complete raw traceback.
- Assertion mismatch: expected and actual values differ
- Import error: a module or symbol could not be imported
- Fixture error: missing fixtures, scope mismatches, or recursive dependencies
- Timeout: a test or operation exceeded its time limit
- Syntax/collection error: parsing or collection failed before a test could run
- Type error: an operation received an incompatible object or argument type
- Connection error: a dependency connection was refused, reset, or otherwise failed
- Unknown failure: deterministic fallback with traceback-first guidance
Selenium and Playwright tracebacks also receive a focused browser automation hint covering selectors, waits, page timing, and element visibility.
Stop doomscrolling tracebacks. Run pytest --why.