Microservices and Testing Pyramid
Adoption of microservices have changed the way we build software. It's a slim down version of SOA and impacts all areas of SDLC. A successful adoption will require mindset change of how we think, design, test, build, deploy and monitor our products.
In this post, I want to discuss Testing methodology which took a 180 degree turn for me. Conventional testing pyramid implies that Unit tests are the most important form of tests. It carries the heaviest weightage. Unit test identifies a small unit of code and test it with combination of parameters. Unit tests are then followed by Service tests. Service tests are the API tests for your service. Usually it consist of a test-suite that includes spinning up the service under test and all its dependencies. A test client can call service API with different inputs and validate that the service is working as expected. At the top of the pyramid are the UI and E2E tests. A typical testing pyramid looks something like:
This pyramid makes perfect sense in the monolithic architecture. Let's take an example of everyone’s favorite calculator. I will write a calculator utility classes. It will have functions to perform mathematical operations. It will be packaged in a binary. The monolithic service will consume this binary at run time using a profile catalog. This binary will be hosted with hundreds of other binaries within this service. All colocated binaries can use the Calculator for their mathematical needs. In this monolithic setup the best way to test functionality is using Unit tests.
Microservice setup is different than monolithic. In microservice architecture Calculator is a standalone functional service exposed over an http API. It can only be consumed by making http calls. Binary coupling is discouraged in microservice architecture. Here is Ben Christensen famous talk on the topic. An ideal microservice should have well defined responsibility with in a bounded context. This kind of setup makes it easy to write effective Service tests. The testing pyramid for microservice architecture should look something like:
What about the cost? We all love writing Unit tests. They are easy to setup, cheap to write (if done at development time), cheap to run, very reliable (meaning if they break - they break for a real reason and not some environment instability). They also produce nice looking code coverage reports. Service tests on the other hand are difficult to setup and expensive to run. In the future posts, i will discuss how adoption of Docker has made it super easy to write reliable and fast Service tests.
In this post, I want to discuss Testing methodology which took a 180 degree turn for me. Conventional testing pyramid implies that Unit tests are the most important form of tests. It carries the heaviest weightage. Unit test identifies a small unit of code and test it with combination of parameters. Unit tests are then followed by Service tests. Service tests are the API tests for your service. Usually it consist of a test-suite that includes spinning up the service under test and all its dependencies. A test client can call service API with different inputs and validate that the service is working as expected. At the top of the pyramid are the UI and E2E tests. A typical testing pyramid looks something like:
Microservice setup is different than monolithic. In microservice architecture Calculator is a standalone functional service exposed over an http API. It can only be consumed by making http calls. Binary coupling is discouraged in microservice architecture. Here is Ben Christensen famous talk on the topic. An ideal microservice should have well defined responsibility with in a bounded context. This kind of setup makes it easy to write effective Service tests. The testing pyramid for microservice architecture should look something like:
What about the cost? We all love writing Unit tests. They are easy to setup, cheap to write (if done at development time), cheap to run, very reliable (meaning if they break - they break for a real reason and not some environment instability). They also produce nice looking code coverage reports. Service tests on the other hand are difficult to setup and expensive to run. In the future posts, i will discuss how adoption of Docker has made it super easy to write reliable and fast Service tests.