At a high level, microservice architecture comprises of many independent composable services to deliver a business solution. Each microservice serves a specific business purpose or functionality. Since each microservice can stand on its own, a medium to large scale architecture can comprise of hundreds or even thousands of services.
An effective microservice test strategy should not only handle the additional levels of granularity and distributiveness, but also ensure the correctness of overall business functions delivered as a system. Testing challenges introduced, are both functional & non-functional in nature. Some of the key challenges are:
- Each granular service capabilities needs to be tested independently to ensure correctness. Typically, a composite service invokes multiple granular services to achieve its functionality, hence the functional correctness of the same will heavily depend on correctness of granular service.
- Since services can be owned by multiple development groups and released independently, sometime the dependent service might not exists while testing a composite service early stage of lifecycle
- Microservices are typically API centric. The service contract between provider and consumer may change over period, hence lack of compatibility management may introduce test automation failure
- Microservice architecture is highly distributed, a single business functionality may trigger multiple service invocations. Additional test capabilities are required to ensure that single service failure in chain of invocation, should not cascade to system failure.
- Microservice are meant to scale elastically, hence performance testing of service is particularly important early in life cycle.
The increase in deployment granularity, surge the complexity of test data management. The overhead of too many moving parts in CI, CD and test automation pipeline requires effective meta data management. This may entail new tools and frameworks for various testing approach. for example, a new test suit is required to validate architecture resiliency capability to a service failure event. This does not mean that earlier testing tools, frameworks and practices that has evolved over years is not applicable. A cohesive testing approach is needed, depending on characteristics, size & scale of application under test. Some of the testing approaches are described below
- Unit Testing of each component: Each Component/unit of a microservice need to be tested for correctness and coverage. TDD approach is also one of the ways to ensure each unit is working as expected.
- Test microservice in isolation: Each microservice as one of the building blocks need to be tested independently. Testing of its functionality and validating input/output as expected. Managing test data for various scenarios for each microservice needs to be thought through.
- Contract Testing: As microservices are independent but still come together to fulfil a business functionality, there is a clear communication protocol or contract definition between them. Testing and ensuring contract are implemented and followed as defined, is a key step in microservice testing approach.We can follow a consumer driven approach, where the consumer service initiates the test, sends request and receive response. Response is validated by the consumer service.Or we follow provider driven approach, where the provider service initiates the test, creates a mock consumer service following the contract definition. Use
Objective of contract testing is to make sure each service individually and collectively follows the contract definition and share changes in contract with the impacted stakeholders much in advance.
- Service Integration Testing: Once all the services and their contracts are tested, actual cohesion of all these services to execute a business functionality needs to be tested. Data flow between the services and outcome of the combination of the services is a key part of this testing. At this point 1st level of service failure testing should be done too.
- End-to-End Test: These Tests include business scenarios which are mostly user behavioural flows which includes UI, Services and Components. As most of the granular test processes are completed during previous phases, only critical business operational flows need to be tested in this phase. Overall performance and Security testing also need to be performed for critical flows in this phase.
- Resilience Testing: As this architecture is an amalgamation of many small services/components, we need to keep testing for failure handling capability of the application. This includes injecting faults into the system randomly or bringing down services to check the behaviour of system thru monitoring. This allows to observe impact on application data and recovery path of the application in case of failure of any of the component.
Microservices are built around business capabilities, by architecture some of these services may have its own local data store and some may heavily depend on downstream system for data dependency. This can trigger, introduction of new interface or changes to existing interfaces of downstream systems. Hence stability of these interface is also especially important from overall system capabilities point of view. In such a scenario overall test strategy should include right mix and match of testing approaches, tools and frameworks to address the problem holistically.
At ESSPL we provide expertise around latest testing processes, frameworks and tools to deliver a unified test solution across different domain and technology landscape. Our test engineers are equipped with modern state-of-art tools and frameworks to manage software releases better and faster.