Contract Testing: Test Interfaces, Not Integrations
Contract testing ensures services work together without slow integration tests. It's a formal agreement where a 'consumer' defines its needs, and a 'provider' proves it can meet them.
THE MENTAL MODEL: Think of contract testing as a legal agreement between two services, a 'consumer' and a 'provider'. The consumer dictates the exact terms: 'I will send you this request, and I expect this specific response structure back.' The provider's only job is to prove it can honor that agreement. This approach tests the interface between services without needing to test the entire integrated system at once.
HOW IT WORKS: The process is consumer-driven. First, the consumer's test suite generates a 'contract' file, typically a JSON document, which captures the interactions it expects to have with the provider. This contract specifies the request method, path, headers, and body, along with the expected response status code, headers, and body structure. This contract is then shared with the provider, often via a central repository called a 'pact broker'. The provider then runs tests against this contract, replaying the consumer's requests and verifying that its actual responses match the contract's expectations. If they do, the contract is fulfilled.
WHEN TO USE IT: Contract testing shines in a microservices architecture. It allows teams to deploy their services independently with confidence. If a provider's tests pass against all its consumers' contracts, it knows it hasn't broken any existing integrations. This replaces the need for slow, flaky, and expensive end-to-end integration test suites that require deploying multiple services just to run a test.
WHEN NOT TO USE IT: Contract testing is overkill for monolithic applications where all communication happens internally. It's also less useful for public APIs with a large, unknown number of consumers, as you can't possibly maintain a contract for every one. In that case, robust end-to-end testing and strict versioning policies are more appropriate. It's designed for testing interactions between services you control.
ONE CANONICAL EXAMPLE: A mobile app (the consumer) needs to display a user's profile. It has a contract with the backend API (the provider) stating: 'When I send a GET request to /api/users/123, I expect a 200 OK response with a JSON body containing a string 'name' and an integer 'userId'.' The backend team can refactor their database or internal logic, but as long as their service still passes this contract test, they know they haven't broken the mobile app's profile screen.
Read the original → en.wikipedia.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.