A Not Brief Intro to Contract Testing

Photo by RetroSupply on Unsplash

A Not Brief Intro to Contract Testing

Before we deploy an application to production, we need to be sure it works correctly with the other applications with which it integrates. To do this, traditionally we run integration tests using "live", deployed applications.

Integration tests

  • ✅ give us confidence to release

but

  • ❌ introduce dependencies

  • ❌ give slow feedback

  • ❌ break easily

  • ❌ require lots of maintenance

    we need something better.......

What is Contract Testing?

Traditionally, Integration Testing has been a major part of a Tester’s chunk of work in a production setup. Integration Testing involve testing two or more microservices together to check their compatibility.

The most famous of Integration Testing is e2e testing which test all microservices as a single environment perfectly resembling as to the application when in production.However, there are some issues with current e2e testing which contract testing solves->

  1. Resource Intensive: E2E testing can be time-consuming and expensive due to the need for comprehensive test cases, the setup of testing environments that mimic production, and potentially longer execution times for tests.

  2. Flakiness and Reliability Issues: E2E tests can sometimes produce inconsistent results due to their reliance on multiple external systems and networks, leading to flakiness in test outcomes.

  3. Slow Feedback Loop: Due to the extensive nature of E2E tests, there can be a significant delay in getting feedback, which can slow down the development process, particularly in agile environments that prioritize quick iterations.

Contract testing is a software development technique that focuses on verifying the agreements (contracts) between different parts of a system. These parts can be individual software components, microservices, or even entire applications.

Here's a breakdown of how contract testing works:

  1. Defining the Contract: The contract outlines the expected behavior for each interaction. This includes details like:

    • The format and content of data requests sent by one service.

    • The format and content of data responses expected by the receiving service.

  2. Testing the Contract: Contract tests are written to simulate how one service interacts with another. These tests verify that the receiving service:

    Understands the request format.

  3. Processes the request correctly.

  4. Send back the expected response format.

Benefits of Contract Testing:

  • Improved Communication: Contract testing clarifies communication expectations between different parts of the system, reducing misunderstandings and errors.

  • Early Bug Detection: By constantly checking if services adhere to the contract, contract testing helps catch integration issues early in development.

  • Faster Development: Automating these checks frees developers from manual testing, allowing them to focus on building features.

  • Increased Reliability: Contract testing promotes a more stable system by ensuring consistent communication between services.

    These are some benefits of Contract Testing

    When to Use Contract Testing:

    Contract testing is particularly beneficial for:

    • Microservices architectures: With many independent services interacting, contract testing ensures smooth communication.

    • Large and complex systems: Contract testing helps maintain consistency and catch integration issues early.

In essence, contract testing acts like a common language for different parts of your system. It ensures everyone is on the same page, leading to a more robust and efficient development process.

A basic design of how Contract Testing works

Contract Testing can be implemented using Pact-Flow-

How Pact helps Consumer side -

  • Pact solves the problem of keeping the two sets of tests in sync by use of a "contract", also known as a "pact".

    During the consumer tests, each request made to a Pact mock provider is recorded into the contract file, along with its expected response.

    How Pact helps Provider Side -

  • A Pact simulated consumer then replays each request against the real provider, and compares the actual and expected responses. If they match, we have verified that the simulated applications behave the same way as the real applications. This means the two real applications should communicate correctly when they interact in real life.

    Using Pact gives you tests that

    • ✅ run independently

    • ✅ give fast feedback

    • ✅ are stable

    • ✅ are easy to maintain

and

  • ✅ give you confidence to release