Contract Testing: The imperative piece in Testing Pyramid

Subhash Kotra
Tide Engineering Team
4 min readSep 12, 2023

Hello Everyone! 👋

As the world shifts from a single, monolithic backend architecture to using micro-services, the dependency on various teams to manage these services increases. If you are a mid-level backend and Automation engineer looking to navigate through this change — this article is for you. It will delve into the world of Contract Testing to answer questions like:

What are Contracts?
Why is it important to test them?
And how can we leverage Contract Tests to reduce the dependency on E2E Tests?

😏Here we go!

💡 Contracts are created from a particular micro-service from both the schema and the key perspectives.

Think about a scenario where an endpoint in micro-service A is used by multiple other services B, C and D as depicted here 👇

Service Dependency

Let’s assume there are some changes to the endpoint in microservice A and the team responsible for them could not communicate with teams B, C and D. In this case, the endpoints in B, C and D would fail whenever there is a call that goes to it.

In normal circumstances, this call occurs only during the E2E Tests, often identifying defects late in the Release cycle.

💡 This is where Contract Tests come in. Automating them helps identify changes early into the release cycle.

In the dynamic landscape of backend microservices, ensuring seamless communication and cooperation between disparate components is pivotal. Contract testing is here for this. It has an essential strategic value for strengthening the robustness and reliability of interconnected micro-services.

Here is where Contract Tests sit in the Testing Pyramid:

Testing Pyramid

Now that issues can be identified right after the Unit Tests itself, chances (if any) of slipping the issues to the upper level are close to zero, in-turn resulting in rapid development cycles.

💡 The tests act as a safety net during deployments, instilling confidence in the changes introduced to the microservices ecosystem.

Let’s take a look at the three components that constitute a Contract Test.👀

Consumer
A Consumer generates and stores their expectations in, what is typically termed as, a Contract file. This file ties its contents to the consumer code. The contract file can be generated in 2 ways:

  • by recording requests & expected responses, or
  • by generating expectations from the class/schema files available in the Consumer code base.

In our example earlier, service A would typically be termed as a Consumer.

Provider
Providers are the services which use the Consumer and validates its service against the Contract file generated by the Consumer. For this to happen, the Consumer must pass the contract file generated to all the providers and at all times whenever there is a change in its service. The providers can be other services who are making a call to Consumers or some Front-end actions, like clicking on a button on a Web-page etc. From the scenario above service B, C and D are typical examples of Providers. And as such, they will again create a dependency on maintaining the Contract Files and this is where Pact Broker comes into the picture.

Pact Broker
A Pact broker is a centrally located storage to maintain all the contracts of an organisation. This can be a self-created ecosystem using AWS or using the PACT FLOW provided by the pact.io. Once a Pact Broker is configured, one needs to provide the details of it in the Consumer and Provider Tests for it to understand the nuances. After these configurations, a Consumer and the corresponding Providers will be communicating with the Pact Broker and validate their Contracts with each other.

The process automates the collaboration amongst all the teams without any dependency on a single person. It also gives us actionable insights which enables us to amplify the reliability and agility of our backend micro-services infrastructure. Hopefully this article is helpful to understand Contract Tests better in order to reduce the deployment cycles in our respective organisations. I strongly recommend using Contract Tests in your day-to-day operations.

🛰️ Empowering your micro-services with the solidity of contracts will revolutionise how Engineers design, develop, and deploy in this ever-evolving domain. 🌌

Good luck!

About the Author

I am Subhash, a QA Automation Lead at Tide — a business financial platform focusing on the needs of SMEs. We concentrate on how best we can automate what we do on a daily basis. My primary interest is to take up new technologies and the challenges associated with them. Outside of work, I am passionate about running, and have completed 4 half-marathons till date.

For more details and questions find me on LinkedIn/Twitter(X)/Email.

--

--