Week 19 - Testing, Property-Based Testing, Mutation Testing, Fakes vs. Mocks¶
19.1 Conceptual Core¶
- The test pyramid still applies: many fast unit tests, some integration, few end-to-end. In Python, the unit tier is so cheap there's almost never an excuse for skipping it.
- Prefer fakes to mocks. A fake is a working implementation with simpler internals (in-memory repo, fake clock). A mock is a script of expected calls. Mocks couple tests to implementation; fakes don't.
19.2 Mechanical Detail¶
pytest: fixtures,conftest.py, parametrize, marks,pytest.raises,pytest.warns,tmp_path,caplog,capsys. Plugin ecosystem:pytest-asyncio,pytest-cov,pytest-xdist(parallel),pytest-benchmark,pytest-mock,pytest-randomly.hypothesis: property-based testing. Strategies,@given,@settings,assume, stateful tests withRuleBasedStateMachine. The single biggest force-multiplier in this curriculum.mutmut/cosmic-ray: mutation testing. Verifies that your tests fail when production code is broken - surfaces vacuous tests.unittest.mock: when you must. Prefermonkeypatchfixture andrespx/vcr.pyfor HTTP.- Test doubles taxonomy: dummy, stub, spy, mock, fake. Know the difference.
19.3 Lab - "The Tests Find Bugs You Didn't Know You Had"¶
- Add
hypothesisproperty tests to your week-3 word counter. Watch them find a UTF-8 boundary bug or an empty-input issue. - Add a stateful
hypothesistest against your tiny ORM from week 5. - Run
mutmut. Identify untested branches. - Replace any
Mockyou used with a fake implementing aProtocol.
19.4 Idiomatic & Linter Drill¶
- Enable
ruffPT(pytest style). Refactorassert x == 1; assert y == 2patterns; prefer one assertion per test.
19.5 Production Hardening Slice¶
- CI gate: coverage ≥ 90%,
mutmutkilled-mutant ratio ≥ 80%,hypothesisprofile--ci.