Services + End-to-End Testing = ?
architecting microservice architecture anti-patternsA common anti-pattern of microservices adoption is using end-to-end testing. In this article, I explain why end-to-end testing undermines one of the key benefits of microservices. I cover why it’s sometimes a band-aid for architectural flaws and why, in some cases, a monolithic architecture might be a better choice.
Microservice architecture = set of independently deployable services
A defining characteristic of the microservice architecture is that each service is independently deployable. A service is independently deployable if it is production ready after being tested in isolation by its deployment pipeline.
The deployment pipeline uses contract tests to ensure that the service can communicate with other services. If the deployment pipeline’s tests pass then service can and should be deployed to production.
End-to-end testing of services = distributed monolith
Some organizations, however, insist on end-to-end testing of the application before release. On the one hand, if the end-to-end tests are thorough, then it gives you confidence that the application works. But the trouble with end-to-end tests is that they are usually slow, brittle and complicated. The end-to-end tests are often a bottleneck that reduces the deployment frequency and defeats the purpose of using the microservice architecture. You have a monolith - the unit of deployment - that’s comprised of services. Or, in other words, a distributed monolith.
End-to-end testing = a band-aid for a flawed architecture?
An organization might use end-to-end testing because they found that service level testing was not sufficient to ensure the application’s correctness. Quite often that’s because the services were not designed to be be independently deployable. For example, perhaps services have unstable APIs.
The problem is frequently made worse by an excessively fine-grained architecture comprised of lots of little services. Such an architecture shifts the focus of development from domain logic to the intricacies of service-to-service communication and, requires more contract tests. As a result, it can be ‘easier’ to use end-to-end testing.
Rather than adopt end-to-end testing, the solution is to fix the architecture. An organization must reduce the number of services. Perhaps at most one service per team unless there is compelling reason for more. Each service should be designed so that it’s independently deployable.
Use a monolithic architecture
If an organization insists on end-to-end testing before release then they should consider migrating to a monolithic architecture. After all, the monolithic architecture is not an anti-pattern. Especially, when the organization consists of only a few teams. By using a monolith, the organization can avoid the complexity of a distributed architecture.
Need help with accelerating software delivery?
I’m available to help your organization improve agility and competitiveness through better software architecture: training workshops, architecture reviews, etc.