Microservices is soon becoming the default standard for building continuously deployed systems in the DevOps world. In the simplest form, a Microservices architecture is an approach to building an application as a suite of small services, each running in its own process and are independently deployable. These services may be written in different languages and may use different data storage techniques. While this results in the development of systems that are scalable and flexible, it needs a dynamic makeover for the testing team. This necessitates that the testing team builds a deep architectural and design understanding and re-invent traditional test techniques. The following is the list of ten steps to help the testing team adopt this change and build its Microservices test strategy:
Step 1: Analyze the architecture to primarily determine three key categories of testable requirements:
- The producer service, which serves as a client to varied consumers
- The consumer service, leveraging the services from different producers
- The orchestration engine, the messaging and coordination layer of these services
- Step 2: Review provider contracts to determine the set of capability that a service provides in the form of interfaces and data schemas to form the basis of your functional tests.
- Step3: Review quality of service and security (WS_Security) clauses in the provider contracts. It will determine nonfunctional requirements for performance, security and volume.
Step 4: Now that we have determined individual services testing requirements, this step will focus on the integration needs. Determine the use pattern of how these services will be consumed. The most common use cases are the following:
- Microservices consumed internally by the application domain
- Microservices integrating with external Microservices for example, digital wallets
- Microservices exposed to the public domain, for example, polling services for real-time rates in the investment banking space
This will form the basis of your integration testing requirements.
- Step 5: Start with unit testing of your services. Test-driven development is best used with automated tools dependent on programming languages such as JUNIT, NUNIT, etc.
- Step 6: The most important test is contract-based testing: This is defined by service contract definitions. In the case of provider services that rely on other services, testing is carried out using test clients as mocks that replicate a service to be consumed. Consumer-driven contract testing is based on contracts that are provided by consumers. These will have clear definitions of interfaces, schemas, and error conditions. Behavior-driven development techniques are best used to define acceptance criteria.
- Step 7: Contract-based testing is followed by integration testing. This is critical for two reasons. First, it helps test the orchestration of the services in case of internal applications. Second, and more importantly, testing with external services outside the application domain.
- Step 8: The next critical test type is performance testing of services: This starts with testing the performance of each individual Microservice and interconnected Microservices. As each Microservice operates in its own process space, with interconnected Microservices, performance degradation is inevitable due to a domino effect. Determining which service performance is not meeting service levels can become very tricky. The best way to build a safety net, particularly for a new implementation, is through continuous monitoring in production where an application that mimics users constantly checks the application for performance issues.
- Step 9: Build security testing from the start. Microservices are transforming the security landscape as they communicate via application program interfaces that are independent of machine and programming language. Unlike scaling across local networks, these are connected to the outside world making traditional end-point security testing a small part of the security tests.
- Step 10: Testing teams often underestimate the need for infrastructure failover testing. Microservices operate in a continually evolving environment, and failover tests are critical to validate application resiliency by removing resources and servers or simulate blocked networks.
Speed, flexibility, and scalability provided by Microservices are the way forward. It is critical that the testing team educates itself on architecture-driven test techniques to meet time-to-market needs with impeccable quality.