4 Pillars of Good Unit Tests
Khorikov describes 4 pillars of a good unit test:
- Protection against regressions (bugs)
- Resistant to refactoring
- Fast feedback
He claims that the first 3 are mutually exclusive and provide a 2-out-of-3 trade off similar to the CAP Theorem trade off. Since maintainability is not mutually exclusive, it should always be maximised. However, some types of tests lend themselves to more maintainabiity: e2e tests for example require a lot more code than a unit test.
Resistance to refactoring should be maximised always, as it is either binary: it is or it isn't. The trade off is then between resistance to refactoring or fast feedback.
An extreme example of this is an e2e test. It is extremely resistant to refactoring but not usually very fast. Another example of this is a heavily mocked method, it is very fast but may not provide good protection against regressions, since the mock can easily make assumptions that don't exist. This example would also fail to score high in the resistant to refactoring pillar.
Khorikov (2020) (Chapter 4)
Vladimir Khorikov. Unit Testing: Principles, Practices, and Patterns. Manning, Shelter Island, NY, 2020. ISBN 978-1-61729-627-7. ↩