← Stackzilla Blog

Contract Tests: Catching API Breakage Between Deployments

Published November 9, 2026 · 3 min read · testing, API design, integration, engineering

Make consumer expectations explicit so an API change does not silently break another service or an older client.

Two services can pass all their unit tests and still fail together. The provider returns `displayName`, while the consumer expects `name`. Or a field changes from nullable to required before an older client is ready. Contract testing focuses on the boundary between those components. It records the interactions a consumer depends on and verifies that the provider can still satisfy them. ## Test what the consumer actually needs A useful contract describes relevant requests and responses: paths, methods, status codes, required fields, types, and meaningful constraints. It should not copy every incidental field just because the provider happens to return it. Overly strict contracts turn harmless additions into failures. Overly loose contracts miss changes that break real behavior. The right boundary is the consumer's actual dependence. Include error responses when the client makes decisions based on them. A frontend that handles a validation failure differently from a permission failure depends on more than the successful response schema. ## Verify both sides of the agreement Consumer-driven tools can generate contracts from tests that exercise the consumer against a controlled provider substitute. The provider then verifies those contracts against its implementation. Provider verification needs predictable data states. A test that assumes a particular customer exists in a shared staging database is vulnerable to unrelated changes. Define the setup required for each interaction. An OpenAPI schema is also useful, but writing a schema does not establish that the implementation follows it. Validate requests and responses where appropriate, and connect compatibility checks to the release workflow. ## Keep the scope honest Contract tests do not prove the complete business process. They may not catch production authorization misconfiguration, network failures, or a sequence of individually valid calls that produces an invalid result. Keep selected end-to-end tests for critical journeys and unit tests for business logic. Contract testing fills a gap between those layers rather than replacing them. Version compatibility matters especially for mobile clients and public APIs, where old consumers can remain active long after a provider deploys. Removing a field requires evidence that supported consumers no longer depend on it. When a contract fails, decide whether the change is accidental or intentionally breaking. An intentional break still needs a rollout plan, communication, and an appropriate compatibility window. The value of a contract test is an early, specific disagreement: this consumer needs this behavior, and the proposed provider no longer supplies it. That is much easier to resolve before either side reaches production. ## Further reading - [Pact: Consumer-driven contract testing](https://docs.pact.io/) - [OpenAPI Specification](https://spec.openapis.org/oas/latest.html)

Read the full article on Stackzilla →