Contract Testing — Cheat Sheet

Tags: testing, microservices, pact, backend, api

Level: intermediate

TL;DR: Contract testing verifies that two separate services (e.g., API provider and consumer) can communicate successfully by checking their interactions against an agreed-upon contract, avoiding slow end-to-end tests.

Key concepts

Ensures API consumers and providers agree on exact requests and responses.

Consumer-Driven Contracts (CDC) means the consumer dictates the expected API shape.

The contract acts as a mock for the consumer and a validation suite for the provider.

Provider verification ensures the API meets all consumer expectations without running the consumer.

Pact is the most widely adopted framework for implementing contract tests.

Pact Broker is a central repository used to share and version contracts between teams.

Contract tests are significantly faster and more isolated than end-to-end (E2E) testing.

They prevent accidental breaking changes in distributed microservice architectures.

Typical questions and ready answers

Q: How is contract testing different from integration testing?R: Integration tests require both systems to be running and connected. Contract tests run independently by verifying each side against a shared static contract file.

Q: Why use Consumer-Driven Contract testing?R: It ensures the API provider only builds what is actually needed and warns them immediately if a change will break a specific consumer.

Q: What should you NOT test in a contract test?R: I never test business logic or complex data states. I only verify the structure, headers, and types of the request and response.

Pitfalls and common mistakes

Using contract tests for functional or business logic testing instead of just structural verification.

Forgetting to version the contracts, leading to false positives during deployments.

Provider teams ignoring consumer contracts and treating them as an afterthought.

Overcomplicating the test setup instead of keeping payload examples minimal and exact.

Snippets and commandsJavaScript

// Consumer side Pact setup example (Node.js)
const { PactV3 } = require('@pact-foundation/pact');

const provider = new PactV3({
  consumer: 'OrderService',
  provider: 'PaymentAPI',
});

provider.addInteraction({
  states: [{ description: 'Payment API is available' }],
  uponReceiving: 'a request for payment validation',
  withRequest: { method: 'POST', path: '/validate' },
  willRespondWith: { status: 200, body: { status: 'success' } },
});

To review

[ ] Study Pact Broker matrix to understand how versioning prevents deployment of breaking changes.

[ ] Review bi-directional contract testing and how it differs from CDC.

References

Pact Foundation Documentation

Martin Fowler's article on Contract Tests

Jarvis Interviews
Jarvis