Appearance
Lesson 03 · Contract Testing
Beyond the 1Z0-830 exam
When services talk to each other, the expensive bugs are interface mismatches — the provider renamed a field, the consumer still expects the old one. Contract testing catches these without deploying every service together, by verifying both sides against a shared, machine-checkable contract. Pact is the dominant tool.
Objectives
After this lesson you will be able to:
- Explain consumer-driven contracts and what problem they solve.
- Describe the consumer and provider verification steps.
- Say why extra provider fields are allowed but missing ones aren't.
- Place contract tests in the test pyramid vs full E2E.
The problem: integration without integrating
Full end-to-end tests catch interface mismatches, but they're slow, flaky, and need every service running together. Contract testing gets most of that safety far cheaper: each side is tested independently against a shared contract.
mermaid
flowchart LR
C[Consumer test] -->|generates| P[Contract / Pact file]
P -->|verified against| V[Provider test]Consumer-driven contracts (Pact)
The flow has two halves:
- Consumer side — the consumer writes a test against a mock provider, declaring the requests it makes and the response fields it actually uses. Running it produces a contract (a Pact file).
- Provider side — the provider replays the contract against the real provider and verifies every interaction still holds.
If the provider later drops or renames a field a consumer relies on, the provider's verification fails — before deployment, not in production.
Required vs extra fields
The crucial rule, which the lab encodes: a consumer specifies only the fields it uses.
java
ContractValidator contract = new ContractValidator()
.expect("id", Long.class)
.expect("name", String.class);
// Provider adds a new field later — still satisfies the contract (forward-compatible):
contract.verify(Map.of("id", 1L, "name", "Gizmo", "addedLater", true)).satisfied(); // true
// Provider drops a required field — contract broken:
contract.verify(Map.of("id", 1L)).satisfied(); // false → "missing field: name"- Extra provider fields → fine. Providers can evolve without breaking consumers.
- Missing or wrong-typed required fields → break the contract.
This asymmetry is what makes independent evolution safe.
Gotcha — contract tests aren't end-to-end tests
A contract test verifies the shape and semantics of the interface, not that the whole system produces the right business outcome. You still want a thin layer of real E2E tests. Contract testing replaces the bulk of cross-service integration tests, not all of them.
Where it sits in the pyramid
In the test pyramid (Module 15), contract tests live just below E2E: more confidence than a unit test about cross-service compatibility, far cheaper and more stable than full integration. For a microservice architecture they're often the highest-leverage tests you can add.
SDET note
The lab's ContractValidator is Pact's core idea in ~30 lines: declare the consumer's expectations, verify a provider response, and report precise violations (missing field: name, wrong type for id). Real Pact adds a broker to share contracts between teams and CI, plus matching rules — but the principle is exactly this.
Key Takeaways
- Contract testing verifies that services agree on their interface, testing each side independently against a shared contract.
- Consumer-driven: the consumer declares the fields it uses → a contract; the provider verifies it still satisfies them.
- Extra provider fields are fine; missing/wrong-typed required fields break the contract — enabling safe independent evolution.
- Pact is the standard tool (with a broker to share contracts); contract tests sit just below E2E in the pyramid and don't replace it.
Lesson Quiz
Contract testing primarily catches…
In consumer-driven contracts, who declares the expected response shape?
A provider adds a new field to its response. The existing contract…
What fails when a provider drops a field a consumer relies on?
Contract tests vs end-to-end tests:
Next: Module 20 · CI/CD & Test Infrastructure. This module's lab is in labs/src/main/java/com/jse21/m19_specialized/.