| name | contract-test |
| description | When two components/services talk (API client+server, producer+consumer, module boundary), pin the contract they share and test BOTH sides against it, instead of only unit-testing each in isolation. Use on integration boundaries, API changes, microservices, public interfaces. Trigger with /contract-test or "contract test", "will this break the consumer", "test the API boundary". |
| version | 0.1.0 |
| user-invocable | true |
| metadata | {"emoji":"🤝"} |
contract-test
Unit tests pass on both sides and integration still breaks, because nothing tested the SHARED contract. This pins the interface two parties rely on and tests both against it.
Why this exists (evidence)
- Consumer-driven contract testing (the Pact pattern) is the established fix for integration breakage in distributed/microservice systems: catch a breaking interface change at the boundary, before deploy, without a full end-to-end environment.
- The failure it targets: provider changes a field/type/status code; provider's own unit tests stay green; the consumer breaks in production. A contract test fails the moment the provider violates what the consumer expects.
When to use
- Any client+server / producer+consumer / module boundary, especially across repos or teams (compose with multi-repo-context).
- Before changing a public API, schema, event shape, or shared type.
- NOT for purely internal logic with no cross-boundary consumer (unit tests / testsmith cover that).
The method
- Name the contract: the exact shape both sides depend on, request + response fields and types, status/error codes, event schema, required vs optional, ordering/idempotency assumptions.
- Consumer expectations: write what the consumer actually needs (not the provider's full surface). This is the contract.
- Test the provider against it: assert the provider produces responses that satisfy the contract (every required field, correct types, documented error codes).
- Test the consumer against it: assert the consumer works against a stub/mock that returns exactly the contract (no reliance on undocumented behavior).
- Run on both, on change: a provider change that breaks the contract fails here; a consumer that needs more must update the contract first.
How to run it
- If a contract tool exists (Pact, schema/OpenAPI validation, JSON Schema), use it: validate responses against the schema both sides agree on.
- Lightweight: encode the contract as a shared fixture/schema; provider test asserts output matches it, consumer test runs against it as a stub.
- Compose with structured-output (the contract IS a schema) and testsmith (mutation-test the boundary handling).
Composes with
structured-output: the contract expressed as an enforceable schema.
multi-repo-context: contracts are where cross-repo boundaries live; the manifest names them.
testsmith: unit/mutation within a side; contract-test across the boundary.
Honest limits
- A contract test verifies conformance to the AGREED contract, not that the contract is the right design. Wrong contract, wrong test.
- It does not replace some end-to-end checks (timing, auth, infra); it removes the large class of shape/type/status breakages.