So you’ve decided to ride the Docker wave and refactor your application to a microservices architecture—or, perhaps, to rebuild it from the ground up to run as microservices. Good for you. As any DevOps engineer will tell you, today, microservices make software delivery more flexible, agile and speedy.
But before refactoring or rebuilding your app under a microservices architecture and calling it a day, it’s important to understand and address how microservices impact the quality assurance (QA) processes that exist within your continuous delivery chain. In some important respects, microservices make software testing more complex. You need to plan for this if you want to adopt microservices effectively, in a way that does not undercut your continuous delivery process.
Below, I take a look at how microservices change QA requirements and processes, and offer tips for ensuring that your software testing process remains smooth as you migrate to microservices.
What Microservices Change
When you run your application according to a microservices architecture, you change more than the architecture of the application. A microservices migration has lots of other consequences, from the way you monitor your app, to the way you address security issues, to the way you run software tests.
That last bit—software testing—is what interests us most here, so let’s take a look at the specific challenges that microservices present for software testing processes and QA teams.
More moving parts
Part of the beauty of microservices is that they break monolithic applications (which are unwieldy and therefore harder to manage) into smaller, discrete units of code. This makes administration easier.
But one challenge that arises from breaking your application into smaller pieces is that you have more pieces to work with.
When it comes to software testing, this means there is more to test. In one respect, it’s easier to test microservices because you can run tests on smaller pieces of code, which in turn makes it easier to identify the root of a problem because there are fewer variables within each test when you test only a specific microservice, rather than an entire application.
On the other hand, microservices also mean that your testing workflow potentially has to be broken down into several distinct segments. Rather than having a single part of your continuous delivery pipeline devoted to testing, you have to have multiple testing processes. In one sense, it’s like the QA section of your continuous delivery pipeline actually consists of many small pipes, each one devoted to QA for a specific microservice.
This complexity can surely be managed. But it requires more planning and coordination across your team than you would typically need when doing QA for a monolith. Are you going to devote specific QA engineers to specific microservices within your app? How will you ensure that your engineers can communicate effectively with each other when software tests reveal a problem with one microservice that could impact other microservices? How will you make sure that the testing environment for each microservice is identical, even though the tests are being performed separately?
These are the sorts of questions you need to answer as you upgrade your QA processes to support a microservices app.
Microservice dependencies and interactions
While each microservice within an application can typically run independently and communicate with other microservices via APIs, it’s only when you combine microservices together that you get a complete app.
From a testing perspective, this creates a new challenge that does not really exist with monoliths. When you run software tests on a microservice, you need to make sure not only that that specific microservice performs as expected, but also that all of your microservices, when put together, compose an application that behaves as expected.
For this reason, it’s important to develop testing routines that model dependencies and interactions between different microservices. Don’t just test the internals of each microservice; also test APIs to make sure that each microservice can interface effectively with others.
It can also be helpful to develop a testing process wherein you test individual microservices first, then test the application as a whole at a later stage. By testing individual microservices, as well as the entire application, you get the benefit of being able to perform tests early in the pipeline on smaller objects by focusing on microservices. But you also later ensure that your application as a whole works properly when the microservices are combined to create the entire application.
Addressing bugs in a microservices architecture
One benefit of a microservices architecture is that, in theory, you can apply an update to one part of an application by modifying a specific microservice without affecting other microservices. This approach helps to keep applications more secure and stable, and is one part of the process for building immutable infrastructure.
In order for this approach to work, however, you need to ensure that any bugs you discover during your QA process can be addressed without having to overhaul the entire application. This requires a testing workflow that allows your QA engineers to identify the root of problems quickly, then work with developers and IT Ops engineers to create and apply a fix for those bugs without disrupting other parts of the application.
Achieving this sort of process requires excellent communication between developers, QA and IT Ops. It also requires that your QA engineers have a thorough understanding of the code and architecture of the application they are testing, so that they can make determinations quickly regarding how to address a bug within a particular microservice with minimal disruption to other microservices.
Also helpful in this respect is an infrastructure that makes it easier for your team to apply updates to one microservice without touching others. Docker containers are a good solution for this purpose. If you develop and test each microservice using a container image dedicated to that microservice, the code can be passed quickly and easily between different parts of your team when a bug needs to be addressed. A fix can also be pushed out quickly to production by redeploying the image for the microservice in question, without impacting other microservices.
Microservices are great, especially when paired with modern infrastructure solutions like Docker. (If you try to run microservices without using containers, your environment will end up looking more like the Service-Oriented Architectures, or SOAs, of the 2000s—which is fine, but is not really a modern microservices approach.)
But when you make the move to microservices, it’s important not to leave QA considerations out of the equation. Just as microservices require an overhaul of your application itself, they also force you to revamp your approach to software testing and QA.
Chris Tozzi has worked as a journalist and Linux systems administrator. He has particular interests in open source, agile infrastructure and networking. He is Senior Editor of content and a DevOps Analyst at Fixate IO.