Unit Testing Tenets¶
Tres Seaver’s unit testing tenets.
Goals¶
Unit tests should:
- be as simple as possible while still exercising the app under test.
- run as quickly as possible to encourage running them frequently.
- avoid couplings with other tests, or with parts of the codebase they are not responsible for testing.
- be idempotent.
Tests should not:
- replace narrative or API documentation.
Rules¶
- Never import the module under test at test module scope.
- Each test case method tests Just One Thing.
- Test case names indicate what they test.
- Don’t share test fixtures between test modules.
Guidelines¶
- Minimize module-scope dependencies.
- Do as little work as possible in the execution path of a single test.
- Make fixtures as simple as possible.
- Use globals judiciously.
- Use stub/mock objects to clarify dependent contracts.
Conclusions¶
- Tests are straightforward to write.
- Excellent coverage.
- Easy to debug/diagnose.
- Quick to run.
- Clarifies thinking about the code and its dependencies.
Demonstration¶
Let’s go back and improve the tests we wrote using Tres’ tenets.
What Do We Want To Fix¶
- Bad test practices (importing things under-test at module scope).
- Bad/missing stubs or mocks.
- Bad fixtures.
- Misuse of globals.
API Talk (Tangent)¶
- Avoid Global State When Possible
- Avoid Designing for Convenience (Don’t Give In To
import
Fascination) - Composition Usually Beats Inheritance
- Avoid Using Others’ Code That Breaks These Rules