This post is part of Roadmap for unit tests, if you haven’t seen it yet, please read it to have clear picture of unit tests topics that I find useful.
Let’s start with the fundamental unit tests topics. This part of the roadmap is dedicated to theoretical concepts of unit tests, although theory is not as valued as practice, but it’s also very important for writing high-quality unit tests.
Unit test fundamental topics part 1
Test accuracy can be defined as the ratio of the errors found to the noise. By errors found I mean situations where an error has been introduced into the code and by noises I mean situations where the test passed but the tested system has errors, such situations are called false negatives. Situations where test failed but the tested system is without errors are called false positives. To increase test accuracy we should aim to increase the error detection and reduce the situation where tests return noise.
Pillars of good unit test are principles that improve tests quality and increase the profit from writing them.
Principles that I appreciate the most
- Protection from regression – test must provide protection against changes that may violate existing functionality,
- Immutability for change – test should be as much as possible immute to internal implementation changes and verify system output rather than the implementation,
- Fast feedback – good test should be run frequently and to achieve this it must be quick and give an unambiguous result,
- Maintainability – for tests it is not enough to be easy to write, they should also be easy to read and extend as the application grows,
- Independence – tests must return the same result regardless of the environment in which they are run and run order.
Test strategies can be divided into white-box and black-box. White-box testing is when we’re fully aware of the implementation details and use that knowledge in unit tests. Black-box is reverse approach. In this test strategy, we don’t know how feature is implemented or we don’t use implementation details to write unit tests.
Test isolation has two approaches that are most commonly used. We can separate everything that is not unit that we want to test by using test double, such an approach is called london style. The opposite approach when we avoid mockups and use real context for the unit we want to test is called classical style.
Assertion style is one of the most important parts when it comes to test maintainability. The best option is output-based assertions, in this case we only test what the tested system returns to us and ignore the way it does it. The next one is state-based, after taking the action, we check the state of the tested system. Communication-based is definitely a less advantageous option, in this case we check the invocation of the appropriate methods, which means that we will tightly connect our test with the way the tested system works, and therefore test is very sensitive to implementation changes.
These are only basic information about the theoretical foundations, I will explain each of them in more detail in separate posts. In the next post in this series I will present the practical topics from the roadmap.
You can find other posts from this series here
What do you think about theoretical topics of unit tests that I find useful? Would you add any points? If you consider it valuable, please leave a comment below and share it with others! It helps me verify whether such knowledge is needed by others.