Contract testing

In software testing, contract testing is a technique that checks whether two services that communicate over an API agree on the shape of that communication: the expected requests and responses are recorded in a contract, and each side is verified against that contract in isolation, without either side running the other. It replaces a slow end-to-end integration test with two fast, independent ones.

The longer version

The contract is a file: for each interaction, the request the consumer sends and the fields of the response it depends on. In consumer-driven contract testing the consumer's test suite generates that file by running against a mock of the provider, and the file is published. The provider's test suite then replays each request against the real provider and checks that the actual response contains what the consumer needs. If a provider team renames a field the consumer reads, the provider's own build fails, before deployment, without anyone from the consumer team being involved.

Outside software the phrase means something else: contract testing is also the industry name for a laboratory that tests physical products and materials under contract, and this page is not about that. Within software the confusion is with integration testing and with mocks. An integration test runs both services together, which proves they work but is slow, environment-dependent and often owned by nobody. A mock of the provider inside the consumer's tests is fast but proves nothing, because the mock returns whatever the consumer wrote. Contract testing keeps the mock and verifies it against the real provider.

A contract that asserts too much trains the provider to ignore it. A consumer that records the entire response, rather than the fields it reads, breaks the provider's build every time an unrelated field changes, and the provider team learns to ignore the failures. A contract that lives only in the consumer's repository and is never verified against the provider is a mock with a longer name. The technique also covers only the shape of the exchange: it proves that the provider returns a field called total, not that the total is right.

Common questions

What is the difference between contract testing and integration testing?

Integration testing runs the consumer and provider together in a shared environment and checks the real exchange. Contract testing splits that into two isolated tests: the consumer's expectations are recorded, and the provider is verified against the record in its own build. Contract tests are faster and fail on the side that broke the agreement.

What is consumer-driven contract testing?

A form of contract testing in which the consumer defines the contract, recording only the requests it makes and the response fields it reads. The provider then verifies itself against every consumer's contract. It is called consumer-driven because the provider learns what it must not change from its callers rather than from its own documentation.

Does contract testing replace end-to-end testing?

Contract testing replaces the integration tests whose only purpose was to check that two services still agreed on an API. It does not replace end-to-end tests of a business flow, because it verifies the shape of each exchange, not the behaviour of the whole. Teams keep a small end-to-end suite and move the API agreement checks to contracts.

Who writes the contract in contract testing?

In consumer-driven contract testing the consumer team writes it, as a by-product of their own tests against a mock of the provider, and the provider team verifies against it. In provider-driven variants the provider publishes a specification and consumers verify their calls against that. Either way the contract belongs to both teams: one writes it, the other runs it, and a change to it is a conversation before it is a commit.

When should you use contract testing?

When two or more services owned by different teams communicate over an API and a change on one side can break the other without anyone noticing until deployment. Microservice architectures, a front end and back end released on separate schedules, and a public API with many consumers are the usual cases. A single team owning both sides of an exchange gains less, because the integration test it already runs tells it the same thing sooner.

Bug reports that arrive ready to triage.

Collect replay, console, network and browser context with the Free plan.

<script src="…/widget.js" data-key="pb_pub_…">