A vertical testing strategy
One of the goals of automated testing is to support you while refactoring, which is a continuous task. Tests should be enablers, not obstacles. Let’s see how.
📝 I’ll use the Arrange-Act-Assert terms (the same as Given-When-Then), which is how tests should be split.
A flawed strategy
I often see codebases that rely on low-level unit tests to test everything; there are just a few high-level tests for happy cases. This derives from the myth that unit tests must be low-level. It’s probably also because writing these tests is more straightforward. However, unit tests are not function or class tests.
A unit test is a disputed and misunderstood concept. Many think it targets a function, but that’s a low-level detail that you should be able to change freely (if the unit were always a function or a class, they would have called it a function test or class test). Even classes, components, and layers are low-level details. The unit is the test subject, which is a fluid concept. Unit tests target observable behavior regardless of the way they’re implemented: