The problem nobody catches
A backend engineer renames a field from customerId to customer_id. Unit tests pass. The pull request gets merged. The mobile team's release fails at the app store review three days later. This is a real story from a client; I have seen variations of it on at least a dozen projects.
Unit tests verify that a function does what its writer thinks it does. Contract tests verify that two services still agree on what they will send each other. They catch a very different class of bug.
📦 What "contract" means
A contract is the shared agreement between two services on the shape of their messages — what fields exist, what types they have, what is optional, and what the response looks like. The contract lives in code, not in a Confluence page.
Three styles of contract testing
- Schema-based. Generate an OpenAPI or JSON Schema from the backend; have the front end and the QA suite validate every response against it. Cheapest to set up.
- Consumer-driven. Tools like Pact let the consumer (mobile, web) declare what it expects; the producer's CI validates that it still meets those expectations. Strongest signal.
- Snapshot-based. Save a known-good response, compare each release against it. Best for stable, public APIs.
A minimal setup that works
For most teams I work with, I start with schema-based testing using OpenAPI plus a simple validator in CI. The setup takes a couple of hours and catches 80% of the breaking changes a fancier setup would.
# In CI, after the backend builds
npm run openapi:generate
npx @apidevtools/swagger-cli validate openapi.yaml
npx dredd openapi.yaml http://localhost:3000
How a QA engineer reads a contract test failure
A failing contract test almost always means one of three things:
- Field renamed or removed: Easy to fix, easy to communicate.
- Type narrowed: Backend now returns a number where it used to return a string. Often unintentional.
- Status code changed: The endpoint now returns 204 instead of 200. The consumer's error handling probably broke.
When NOT to contract test
Contract testing is overkill for a single-team service that has one consumer and changes daily. The overhead is not worth it until you have at least two consumers or a stable public API.
QA tip: Treat your contract suite as living documentation. When a backend engineer asks "what does the front end actually use from this endpoint?", the contract should answer in 30 seconds.
Conclusion
Contract tests are cheap insurance against the most embarrassing class of API bugs. Set them up early, keep them lightweight, and trust them. If you want to read more on the QA side, see UX Testing and The Future of QA.




