What pytest Does
- Auto-discovery — finds
test_*.pyfiles andtest_*functions - Assertion introspection — plain
assertwith detailed failure diffs - Fixtures — DI for test setup/teardown (function, class, module, session scope)
- Parametrize — run same test with multiple inputs
- Markers —
@pytest.mark.slow,@pytest.mark.skip, custom - Plugins — 1200+ on PyPI (pytest-cov, pytest-xdist, pytest-mock, pytest-asyncio)
- Conftest — shared fixtures across test directories
- Temporary directories —
tmp_pathfixture - Capture — stdout/stderr capture per test
- Parallel — via pytest-xdist
Comparison
| Framework | Style | Fixtures | Plugins |
|---|---|---|---|
| pytest | Function-based | DI (fixtures) | 1200+ |
| unittest | Class-based | setUp/tearDown | Limited |
| nose2 | Mixed | Limited | Some |
| doctest | Inline | None | None |
FAQ
Q: pytest vs unittest? A: pytest is more concise (no class needed), with better assertions (no assertEqual) and a stronger fixture DI. The vast majority of new Python projects use pytest.
Q: How to test async code?
A: pip install pytest-asyncio, then use @pytest.mark.asyncio async def test_xxx() to await async functions.
Q: Fixture scope? A: function (once per test), class, module, session (once for the entire test run). Larger scope means lower setup overhead but weaker isolation.
Sources
- Docs: https://docs.pytest.org
- GitHub: https://github.com/pytest-dev/pytest
- License: MIT