pytest Highlights Summary
Every highlight bullet from the 12 pages in this section, gathered on one page and grouped by the page it came from.
- A pytest fixture is resolved through dependency injection by parameter name, not by inheritance or explicit wiring
- Collection - discovering which functions are tests - happens before any test runs, and import errors during collection look like failures
- Fixture scope controls a lifetime trade-off between isolation and setup cost, not just where code happens to live
- Parametrization and property-based testing sit on the same spectrum - enumerated cases versus generated, shrunk ones
- Coverage measures what pytest executed, never what was actually asserted
- pytest discovers tests by convention with no boilerplate test classes needed
- Setup requires tests directory, pyproject.toml config, and pytest dev dependency
- Name test files as test_ or test, functions as test, classes as Test
- Prefer pyproject.toml tool.pytest section for config over pytest.ini legacy files
- conftest.py holds shared fixtures and hooks loaded automatically per directory
- Mirror src structure inside tests directory and set pythonpath to src
- Clear test structure makes failures diagnosable in seconds
- Arrange-act-assert with plain asserts is the foundation of readable tests
- pytest shows actual and expected values on failed asserts automatically
- One behavior per test function prevents unclear failure messages
- Use simpler assertions like assert x instead of assert x equals True
- Add messages to complex asserts for clarity when they fail
- Define test dependencies once in conftest.py and inject by parameter name
- Choose fixture scope based on reuse level: function, class, module, or session
- Use yield to run cleanup code after each test completes
- Compose fixtures by naming other fixtures as parameters
- Avoid scope mismatch: never let broader scope depend on narrower
- Override fixtures by redefining in subdirectory conftest.py
- Run one test against many input-output pairs with clear per-case failures
- Use for boundary value testing and replacing copy-pasted test functions
- Create separate tests from multiple input tuples in one decorator with descriptive IDs
- Use custom test IDs via ids argument to make failures easy to identify
- Combine two parametrize decorators to create Cartesian product of all combinations
- Split parametrize table by category when more than fifteen rows become unreadable
- Replace external dependencies with mocks to test logic without hitting real services
- Use monkeypatch for simple replacements, patch decorator when you need call assertions
- Patch where the name is imported in your module, not where it was originally defined
- Use mocks to verify interactions, spies to wrap real objects, fakes for simplified implementations
- Avoid mocking code under test or over-mocking external logic to prevent vacuous tests
- Patch datetime by patching the object in your module and set now return value for time mocking
- pytest-asyncio runs async tests natively without manual event loop management
- asyncio_mode auto detects async tests automatically without explicit markers
- Function-scoped event loops prevent state leaks between async tests
- Use AsyncMock for async functions to properly handle awaited return values
- Missing pytest-asyncio causes async def tests to silently never run
- Let pytest-asyncio manage loops to avoid loop is closed runtime errors
- Coverage shows executed lines, use it to find untested gaps before release
- 100% coverage does not mean good tests; pair with mutation testing and review
- Enable branch coverage to catch conditional else branches in your code
- Target 80-90% coverage on critical paths instead of chasing perfection
- Coverage gates need PR review to avoid skipping important untested branches
- Use diff-cover to report coverage only on changed lines in pull requests
- Hypothesis generates random inputs to find edge cases and shrinks failures to minimal examples
- Use property testing for large input domains, invariants, and validation logic edge cases
- Strategies generate diverse inputs automatically with constrained generation for valid domains
- Assume skips invalid preconditions without failing tests during example generation
- Avoid broad strategies, non-deterministic code, and ignoring shrunk failure examples
- Hypothesis discovers unknown edge cases while parametrize tests known cases
- Use framework test clients to run API tests in-process without starting a server
- TestClient runs your ASGI app in-process for JSON request and response testing
- Override FastAPI dependencies with app.dependency_overrides in test fixtures
- Prevent test interference from shared mutable app state by using fixture scope
- Test error responses explicitly by asserting 400 401 404 and 422 not just 200
- In-process testing is faster and more deterministic than server-based testing
- Automate testing across Python versions and dependency sets in one command
- tox config via INI files, nox config via Python code
- Prevent nox and tox slowness by caching dependencies with uv pip install
- Match testing matrix to your requires-python range to avoid breaking older versions
- Use nox or tox as single source of truth for both local and CI runs
- Complete matrix should finish in under 10 minutes by parallelizing and caching
- One behavior per test so failures pinpoint exactly what broke
- Mock external APIs and databases but test real implementation logic
- Run full test suite in under 60 seconds with individual tests under 100ms
- Use fixtures for shared setup and factory fixtures for flexible test data
- Enforce 80 percent coverage floor on source code with branch coverage enabled
- Delete dead tests immediately and separate unit tests from integration tests
Revisado por Chris St. John·Última actualización: 31 jul 2026