How does contract testing let two teams deploy independently, and what does it not tell you?
Show the full answer Hide the answer
What is being tested
Whether you understand the specific mechanism, and whether you know the limits — which is where over-reliance causes problems.
How it works
The consumer publishes a contract describing only the parts of the provider's response it actually uses. The provider's build verifies its implementation against every published contract.
Two consequences follow:
A breaking change fails a build, not an environment. The provider learns at commit time that a change would break a named consumer, before anything is deployed and without either service running.
The pipeline can answer the deployment question. With a broker holding both contracts and deployment state, a service can ask: can I deploy this version to production, given what is currently running there? That is what makes independent deployment safe rather than hopeful.
The critical detail is only what it uses. A contract asserting the whole response shape means the provider can never add, remove or reorder anything — which is worse than having no contract.
What it does not tell you
Whether the business flow is correct. A contract verifies the shape and semantics of one interaction. It says nothing about whether the sequence of interactions produces the right outcome. If the order service correctly calls the payment service and the payment service correctly responds, and the overall checkout is wrong, contract tests are all green.
Whether the integrated system performs. Latency under fan-out, resource contention, connection pool behaviour — none of it appears.
Anything about consumers who have not published a contract. Coverage is exactly the set of consumers participating.
Non-functional behaviour — error handling under load, timeouts, retry interactions.
So a handful of end-to-end tests for critical journeys remains necessary. What contract testing does is allow that handful to stay small, which is its real contribution.
What makes it decay
- Verification not blocking the build. A nightly check posting to a dashboard is ignored within a month.
- Contracts written by hand rather than generated from real consumer tests, so they document intentions rather than usage.
- Stale contracts kept for consumers that no longer exist, freezing the provider for nobody.
- Over-broad contracts, which is the most common implementation error.
The gap most organisations leave
Contract testing applied to synchronous APIs while event schemas go ungoverned — even though published events have more consumers, less visibility, and the same failure mode. The equivalent mechanism is a schema registry with compatibility rules enforced in CI, and the reasoning is identical.