Best Practices – MicroServices – Contract Testing

Overview:

Microservice is a software architectural style in which a software application is developed as a set of loosely coupled, small and modular services. Each service implements a business functionality & they expose their services to the consumer via a lightweight mechanism (usually REST API).  Consumer here might not be the actual end users – It is usually application UI layer or another service.

As these services could communicate among themselves, there is a chance that changes in a microservice could affect the other services functionality. We will see how to overcome this challenge in this article.

Monolith application:

To better understand the modern microservice architecture, lets first understand the old monolith architecture in which UI, business logic and data access layer – everything was tied together. We used to deploy a big fat EAR file on the server. So, any code change in a business functionality requires thorough regression testing of the whole application.

monolith
As you see, it is not very scalable! If one of the business functionality (say some of kind of file processing) consumes more memory/CPU, to support the load, we need more servers which runs everything as shown below.

monolith-scale

MicroServices:

In microservice world, each business module is created as a separate service. Any business functionality requirement change requires a code change in a specific service and testing of that service. It is easily scalable. So, maintenance/testing should be easier. right?

microservice

Yes, if the software design is as per the above image. However in reality, actual communication might not be like above image – mostly it would be as shown below where a service A might depend on another service B which in turn might depend on another service C. So, code changes in a service C could break other services (A & B) functionality.

 

microservice-reality-1

 

Service Contract:

As these microservices communicate among themselves, we can assume that there is some type of agreement among them. Because they know how to invoke another service, what to send in the request and what to expect in the response. We can call this a service contract! The issues arise only when contract changes.

In the above image, initially all these services were in Version 1. Service C was expecting ‘firstname‘ and ‘lastname‘ in the request to send a proper response to the calling service. Suddenly as part of a business requirement – Say Release 2, the service C is modified to expect ‘DOB‘ in the request. So Service C alone is modified – it has a different version (v 2) – all other services remain untouched!

microservice-reality-2

If other services are not aware of this change, Service C broke the contract. It will definitely break any Service which depends on Service C. If the contract passes even after the code change, We can safely assume that a change in the service C will not affect other services depend on Service C.  Usually this kind of issues can not be identified during the unit testing phase as it happens in the service end point.

Contract Testing:

Contract Testing is done assuming the service under test as a BlackBox – without worrying about the internal structure of the service! It is usually consumer’s responsibility to have a set of tests! Again I do not mean the actual end users as consumer here. Instead anything which uses these services is a consumer – it could be the UI layer or another service.

We do NOT do a very thorough testing of a service. Instead we ensure the request is accepted by the service and a proper response is sent within the accepted response time limit!!

JMeter – MicroService Contract Testing:

TestAutomationGuru has already explained how to do REST API testing using JMeter in the below articles.

I would suggest you to read those articles to implement REST API testing for your current application. It is easy to implement a spreadsheet driven framework for the microservices testing as shown below.

 

rest004

Duration Assertion:

In contract testing, Other than verifying the service response text – we also verify the response time (depends on your requirement). Lets assume, I have a contract test plan as shown here. I have assertions to verify if the response is as expected. One more assertion is to verify the if response is received within 100 milliseconds. So I use a duration assertion.

microservice-rest-plan

After executing the test, The result is as shown below – one of the services failed as it took more than accepted response time range!

microservice-rest-result

 

Contract Testing In Continuous Delivery Pipeline:

In one of our applications, we have many microservices and we follow agile methodology for application development. We have thousands of automated test cases to do a system end-to-end testing. So, as these services are being modified on a daily basis, there is always a chance that service contract might break. Obviously it would break the end-to-end business functionality and test cases used to fail. We used to spend time analyzing these regression issues. In order to save time and get the immediate feedback on the services, before performing the automated regression in the continuous delivery pipeline, We need to perform microservices Contract testing to ensure that none of the services breaks the contract.

ms-c-pipeline

So, we proceed with the functional / performance testing of these services only when the contract passes.

 

 

Happy Testing & Subscribe 🙂

 

Share This:

5 thoughts on “Best Practices – MicroServices – Contract Testing

  1. Hi Vinoth, can u please mention some best practices that you followed by running the GUI tests based on API test run results?. Do we have a chance to get the API results and create a dashboard that can serve the for GUI automation purpose?. The dashboard should help me know which environment to run the GUI tests so that based on the results, my E2E GUI scripts will be triggered every night in that environment where the API is working fine. Please let me know your thoughts on this.

    1. If you currently have a pipeline & GUI tests are followed after API tests in your pipeline, then GUI tests can be controlled to execute only after successful API tests / some pass %. If you need to collect the results in central location, you could take a look at this – http://www.testautomationguru.com/selenium-webdriver-real-time-test-execution-results-using-elasticsearch-kibana/. It is not specific to Selenium. You could implement something similar for your API as well.

  2. Hi Vinoth,
    Are we segregating the provider API’s only and verifying their schema here? Is it a recommended approach to use tools like PACT for this ?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.