This chapter focused both on the architectural and technical aspects of testing different parts of the software. We looked at the testing pyramid to understand how different kinds of tests contribute to the overall health and stability of a software project. Since testing can be both functional and non-functional, we saw some examples of both these types.
One of the most important things to remember from this chapter is that tests are not the end stage. We want to have them not because they bring immediate value, but because we can use them to check for known regressions, when refactoring, or when we're changing the behavior of existing parts of the system. Tests can also prove useful when we want to perform root cause analysis as they can quickly verify different hypotheses.
Having established the theoretical requirements, we showed examples of the different testing frameworks and libraries we can use to write test doubles. Even though writing tests first and their implementation...