Successful strategies to Micro services architecture testing
“Chaos was the law of nature; Order was the dream of man.”
True to Henry Adams’s quote, testing in a Micro services world is often met with chaos but we end up craving for order.
Let us begin with a brief overview on the two preferred architectures that developers continue to use based on the merit it brings to product lifecycle.
Monoliths vs Micro Services:
Consider Monoliths as a box of assorted cookies while Micro Services is each cookie flavor in its own box. Let me illustrate this with an e-commerce example.
In the figure 1 given above the monolithic architecture (to your left) is all encompassing with the business logic, UI, Data Access Layer which translates to storefront, account, inventory and shipping service in an ecommerce app, all built into one.
Let us weigh the pros and cons of using Monoliths:
- Monoliths are easy to deploy with a single or few ‘war’ or containers to deploy all located in the same server
- It is also easy to scale. In case there is huge demand the organization will have to just deploy the same container across multiple nodes
- When it comes to team culture it is one team manages it all
- It is easy to communicate within teams
- It is built on top of a single codebase making it easy to manage
- Huge codebase to manage. Multiple commits from teams can take longer to review and build the app
- Debugging is tricky for new comers. A developer may require a sharp learning curve before starting to code or debug
- Overloaded container means it will take long time to build and longer to deploy
- Entire container brought down during deployments and probably significant downtimes
- Moving to latest technologies is almost impossible. You will have to rewrite the entire codebase
- Limited innovation since each innovation cycle requires multiple party in a group to innovate, but requires sign-off from all parties concerned when you wish to add it
The Micro services:
Micro services solve the problem of breaking down large scale enterprise functions in multiple smaller services with many advantages to its merit.
- Each micro service functions in its own container. In the architecture example stated in Figure 1 (right), every functional unit is broken down in its own container by Business Logic, UI, Data Access Layer. For ex: A storefront and inventory in will run in its own services.
- Micro services will require different teams to own the functional area to manage and add code
- Teams can be allowed to choose their technology stack since the common interface between services is often REST APIs.
- Services can be deployed independently if there are no dependencies on other services
- Since services work within their own virtual machines there is limited performance impact. If a service is impacted, it can be isolate and brought down for maintenance or a code fix.
- Needless to say a ton of innovation is possible since the teams are usually split by functional areas and are free to choose the technology stack of their choice. Teams can become experimental in their isolated environments and later expose APIs to integrate between services.
- With so many services deployed and third party integrations it is imperative that the team does extensive documentation for better maintenance.
- Micro services are DevOps nightmare to deploy a new system or update an existing one. A good strategy and complete automation will be required to deploy several systems if there are multiple integration pieces to be deployed.
- When services are integrated it is critical that the data related changes must be communicated between teams. For ex: a critical piece like a login service in an e-commerce website will require all services to update their SDK to support authentication and maintain session consistency.
- Should a service become bigger a strategy may be required to decouple or decompose the service.
- Micro services are culture driven, it may require management approval to implement, to decouple teams and perhaps decomposing an existing monolith to micro services in certain cases.
Challenges in testing Micro Services:
Figure 2 A typical Micro services layer (Image source: www.martinfowler.com)
Let us start with a typical Micro Services architecture as stated in Figure 2.
A micro service is self-contained with its own service layer, repositories, gateway, data mappers (in case there is a common database) and a client that talks to other services or to an external client.
The key challenges to testing services are:
- Ensuring complete coverage which could be end-to-end or just testing the API in a micro service.
- In case a functional requirement requires changes to multiple services then Coverage across all services to be tested (refer Figure 3 below).Figure 3 (Image source: www.martinfowler.com)
- There could be third party integration points that requires to be tested.
- Non-functional coverage such as performance or security may be covered as well to see the impact due to introduction of new code or even a service (case in point Figure 4 below).
- Coverage could be dependent on other teams as well who may own and maintain the micro service.
Figure 4 (Image source: www.microservices.io)
In our next part let us find different approaches to testing micro services for better test coverage.