When migrating to microservices from a monolith, you will find that automated testing of microservices presents both new and familiar challenges. How many tests should each service have? What tools should I use? How do I ensure correctness between services? Fortunately, the underlying principles remain the same and with some tweaking we can successfully test our microservices.

Let’s start by looking at the Test Pyramid. For this blog post, we’ll consider Martin Fowler’s version (but we’ll broaden UI tests to include all end-to-end tests).

Test Pyramid


The pyramid essentially helps us think about the different test scopes. As you move down the pyramid, your test scope reduces but the number of test cases increases. This means you’ll want to have a few end-to-end tests, a moderate number of service tests and many unit tests. But what type of testing should you do within each layer?

Testing within each layer typically has different goals in mind and employs unique types of testing. Brian Marick has come up with a concept called the Test Quadrants that attempts to model this.

Test Quadrant


The quadrants include a lot of different types of testing, and each can be useful at certain times. What you choose will depend on what your system does, how it’s architected and the characteristics of your system’s users. In terms of automated testing for Microservices, we will exclude manual testing and focus primarily on the left-hand side quadrants (Property tests are for non-functional requirements and while important they won’t be addressed here).

We can combine the pyramid with the quadrants to get a more detailed picture of each layer of testing and what types of automated testing are appropriate for that layer.

Automated Testing by Layer


Putting this all together and applying to microservices, what we want is a lot of unit tests for each microservice, a moderate number of service tests for each microservice, and a few end-to-end tests that test all of the microservices. If you’re on a Java stack, this could look something like this:

  • Unit Layer
      Unit tests using JUnit or TestNG
  • Service Layer
      API tests that test each microservice in isolation using Postman, SoapUI or other appropriate tool to drive the tests and Mountebank for test doubles
      Consumer-driven contract testing using Pact to guard against API breakage
      Integration tests as needed for testing interactions with data sources, external components, etc. using JUnit or other appropriate tool
  • End-to-End Layer
      User journey testing for a few core user journeys using Gauge

Automated microservices testing presents its own unique challenges, but by leaning on and extending what we already know from monoliths, we can formulate a successful test automation strategy. At Calavista, we believe in software development without the drama, and that includes testing too.