Microservice architectures enforce clearer, more pronounced internal boundaries between the components of an entire system than monolithic applications typically do. This can be used to the advantage of testing strategies applied to microservices; more options for places and methods to test are available. Because the entirety of the application is composed of services with clear boundaries, it becomes much more evident which layers can be tested in isolation.
The Five Layers of Testing
An application designed in a microservices architectural style can be viewed at several levels of granularity. Starting from the outside in, end users will interact with the system as a whole. At the next level down, the system internals can be viewed as a series of communications between each of the underlying services. Finally, the services themselves can be described as the code modules that make up each of the services. Testing strategies should aim to cover all these levels or layers, as well as interlayer communication.
Microservice testing follows pyramid model and the key thing to take away is that as we go up the pyramid, the test scope increases, as does confidence that the functionality being tested works. On the other hand, the feedback cycle time increases as the tests take longer to run, and when a test fails it can be harder to determine which functionality has broken. As we go down the pyramid, in general the tests become much faster, so we get much faster feedback cycles. We find broken functionality faster, our continuous integration builds are faster, and we are less likely to move on to a new task before finding out we have broken something. When those smaller-scoped tests fail, we also tend to know what broke, often exactly what line of code. On the flipside, we don’t get a lot of confidence that our system as a whole works if we’ve only tested one line of code! When broader-scoped tests like our contract service test or end-to-end service tests fail, we will try to write a fast unit test to catch that problem in the future. In that way, we are constantly trying to improve our feedback cycles.