SoftwareTestPilot
API TestingPublished: 13 min read

Contract Testing with Pact — Consumer & Provider (2026)

Pact contract testing explained: consumer-driven contracts, provider verification, the broker, and CI wiring that catches microservice breakages before they reach staging.

Avinash K
Founder & QA Engineer at SoftwareTestPilot
Share:XLinkedInWhatsApp
Pact contract testing — consumer-driven contract flow across services.
Pact contract testing — consumer-driven contract flow across services.

Last updated 2026-07-20 · 13 min read · By Avinash K

In a microservices world, integration tests scale badly and end-to-end tests scale worst. Consumer-driven contracts with Pact catch cross-service breakages in unit-test time. Every serious platform team runs Pact — this guide gets you productive in an afternoon.

Key takeaways

  • What consumer-driven contracts are and why they beat integration tests.
  • A consumer test that generates a pact file.
  • A provider verification test that fails builds on incompatibility.
  • The Pact Broker: publishing pacts and gating deploys with can-i-deploy.

1. Why contract testing

End-to-end tests grow O(n²) with services and go red every deploy. Contracts assert only what the consumer uses from the provider. Consumer-side is fast (a mock server); provider-side runs against the real service. Break the contract, break the build — never in staging.

2. Consumer test — Node.js example

import { PactV3, MatchersV3 } from '@pact-foundation/pact';
import { getOrder } from '../src/orderClient';

const { like, integer } = MatchersV3;
const provider = new PactV3({ consumer: 'web', provider: 'orders-api' });

test('getOrder', async () => {
  provider.addInteraction({
    states: [{ description: 'order 4211 exists' }],
    uponReceiving: 'a request for order 4211',
    withRequest: { method: 'GET', path: '/orders/4211' },
    willRespondWith: { status: 200, body: like({ id: integer(4211), total: 100 }) },
  });
  await provider.executeTest(async (mock) => {
    const order = await getOrder(mock.url, 4211);
    expect(order.id).toBe(4211);
  });
});

Running this generates pacts/web-orders-api.json — the contract.

3. Provider verification

import { Verifier } from '@pact-foundation/pact';

new Verifier({
  provider: 'orders-api',
  providerBaseUrl: 'http://localhost:3000',
  pactBrokerUrl: 'https://broker.example.com',
  publishVerificationResult: true,
  providerVersion: process.env.GIT_SHA,
  stateHandlers: {
    'order 4211 exists': async () => { await seedOrder(4211); },
  },
}).verifyProvider();

The verifier replays each interaction against the real service. If the provider changed the response, the build fails with a precise diff.

4. Pact Broker + can-i-deploy

# Publish from consumer CI
pact-broker publish pacts --consumer-app-version=$GIT_SHA --tag=main

# Gate provider deploy
pact-broker can-i-deploy --pacticipant=orders-api \
  --version=$GIT_SHA --to-environment=production

The broker stores every pact + verification. can-i-deploy blocks a deploy if any consumer's verified version is incompatible. See the official Pact docs.

5. When contracts beat other approaches

SituationBest fit
Two internal services owned by 1 teamIntegration tests
Many services, many teamsContracts (Pact)
Third-party you cannot controlRecorded HTTP + monitoring
End-user flows across all servicesSmall suite of E2E on top of contracts

Combine Pact with REST Assured or Postman for regression, and see our API testing interview prep for contract-testing questions asked at senior interviews.

Contract tests are one layer of a wider plan. Our microservices testing strategy shows where Pact sits alongside component, integration, and end-to-end coverage so you don't duplicate the same assertion at four levels.

Frequently asked questions

1.Is Pact only for REST?
No — Pact supports message-based contracts too (Kafka, RabbitMQ, SNS). GraphQL support is via HTTP interactions.
2.Do I still need integration tests with Pact?
Fewer, but yes — for consumer logic that isn't captured in the contract. Contracts don't replace unit tests either.
3.How does can-i-deploy work?
It queries the broker for every pact the deploying service participates in and checks each has been verified against the target environment tag.
4.Pact vs OpenAPI-based contract testing?
OpenAPI is provider-driven schema; Pact is consumer-driven. Use OpenAPI for shape, Pact for behavior. Many teams use both.