Microservice Testing Strategies
This article contains Microservice testing strategies. Learn more about testing in layered architectures.
Join the DZone community and get the full member experience.Join For Free
Microservices are distributed in nature, in any architecture there can be many microservices involved. There are various components involved in any microservice like service can consume events from ActiveMQ or a Kafka topic, saves the data in the Database (both RDBMS or NoSQL) in one go, and then produce the new enriched event to another Kafka topic for other services to consume and start its processing or invoking altogether a separate RESTful service. Writing meaningful test cases in the architecture is not straightforward. The article focuses on a possible testing strategy for cleanly separating the various test cases in the application.
Consider a Pyramid having three layers L1, L2, and L3. The first layer of the Pyramid is L1, the second one is L2 and the third one is L3, any microservice architecture should have three different types of Test cases categorized as L1, L2, L3, these layers are just for our visualization don’t try to create packages for each one of them, let’s understand them in detail.
In Layer-1 / L1, developers need to identify the classes in the code which has most of the business logic, the L1 should only focus on testing the classes which have most of the business logic, developers need to prepare a list of such classes and come up with test cases for them, the one rule what I followed here is don’t try to mock anything here they are the most simple test cases with basic assert statements ensuring all the business logic functionalities are covered.
Consider a service, which inserts the records in the Database and produces a new enriched event to Kafka topic.
In Layer-2 / L2, we will test end to end but by Mocking all the external components like Database or Kafka or RESTful service. In the SpringBoot application if we are using SpringDataJPA by mocking the database it meant is to mock the repositories. The below code highlights the L2 test case in a nutshell,
The test case is straightforward, we mocked the RoomRepository and wrote our test case around that.
Now comes the most complicated one of the Pyramid, L3 test cases. L3 test cases are the actual integration test cases, in my humble opinion in microservices architecture integration test cases should not be part of the service itself, mainly because of two reasons
- Integration Test cases increase the build and service deployment time.
- Integration Test cases increase the build-failure chances, during the build and deployment time what if any external component not necessarily the database but other restful services which our service is using is down, in that case, the Integration test case will fail and the build.
The integration test cases should be maintained separately as a separate service of Integration test cases or an automation integration test suite. These test suites should be updated on regular basis with all the event model changes etc., this service should be maintained both by QA and Developers, and writing the automation test case should be part of the acceptance criteria. Integration Test cases for me hold a special place in the software development lifecycle, these test cases can also help us in a big way during debugging any production issues.
In a microservices architecture, we need to focus on writing efficient test cases not just flooding the application with lots of useless test cases just to keep up with code coverage percentage like writing test cases for Setters/Getters is of no help. Also, the focus should be on writing the test case which can help us throughout, the test cases should be written neatly so that any new joiner can understand the application just by looking at the test cases.
Opinions expressed by DZone contributors are their own.