API Platform & Lifecycle · Governance and Quality

Contract Testing: Pact and Schema-Based Testing

Verify providers and consumers agree without full end-to-end environments.

Consumer-driven contract testing (Pact) records what each consumer actually uses as contracts; the provider's CI verifies it still satisfies every consumer — catching breaking changes that matter in practice. Schema-based testing validates implementations against the OpenAPI spec and generates many requests (Schemathesis, Dredd) to find crashes and spec violations. Bi-directional contract testing (PactFlow) compares consumer expectations with the provider's OpenAPI spec.

Testing approaches

Criterion Consumer-driven (Pact) Schema-based (Schemathesis) End-to-end tests
Catches Breaks affecting real consumers Spec violations, crashes Integration issues
Needs other services running No Provider only Everything
Speed Fast Medium Slow
Maintenance Contracts per consumer Spec quality High (flaky)
const provider = new PactV3({ consumer: "web-app", provider: "orders-api" });

it("gets an order", () =>
  provider
    .given("order ord_1 exists")
    .uponReceiving("a request for order ord_1")
    .withRequest({ method: "GET", path: "/v1/orders/ord_1" })
    .willRespondWith({ status: 200, body: like({ id: "ord_1", status: "paid", total: { amount: 2400, currency: "EUR" } }) })
    .executeTest(async (mock) => {
      const order = await getOrder(mock.url, "ord_1");
      expect(order.status).toBe("paid");
    }));

Common pitfalls

  • Contracts that assert exact values instead of shapes/matchers.
  • Provider states that are hard to set up.
  • Relying only on end-to-end tests for compatibility.

Key points

  • Pact verifies real consumer usage
  • Schemathesis fuzzes against the spec
  • Both run in CI without full environments

Further reading: Pact documentation

Practice questions

What does consumer-driven contract testing catch that schema diffs might miss?

Answer

Behavior and data that consumers actually depend on (e.g., a field being present for a given state), and it tells you exactly which consumer would break.

What kinds of bugs does property-based API fuzzing find?

Answer

500 errors on unusual inputs, responses not matching the schema, missing validation, and inconsistent status codes.

Open in the app to mark lessons complete, take notes and track your progress.