SA-201b · Module 3
Contract Testing
3 min read
Integration tests that call real systems are slow, flaky, and expensive. Contract tests verify the agreement between producer and consumer without requiring both systems to be running. The producer publishes a contract — "I will respond with this structure." The consumer tests against the contract — "I expect this structure." If either side breaks the contract, the test fails before the integration breaks in production.
- Define the Contract The contract specifies the request format, response format, status codes, and error structures for each endpoint or message type. Write the contract as a machine-readable specification — OpenAPI for REST APIs, AsyncAPI for event-driven systems. The specification is the source of truth.
- Producer Tests The producer tests that it generates responses matching the contract. If the producer changes a field name, the contract test fails. If the producer adds a field, the contract test passes (backward compatible). If the producer removes a field, the contract test fails (breaking change). The producer side catches breaking changes before they ship.
- Consumer Tests The consumer tests that it can parse and handle the contracted response format, including edge cases — null fields, empty arrays, error responses. Consumer tests verify that the consumer is robust against the full range of valid producer behavior.