Contract Testing Basics

Contract testing checks that the contract between services (request/response format, field types) matches, so interface changes do not cause integration failures. Common tools: Pact, Spring Cloud Contract. This article explains the idea and usage with a reference table.

Overview

  • Contract: Agreement between Consumer and Provider (API spec, request/response examples). Can be JSON Schema, OpenAPI, or tool-specific format.
  • Consumer-driven: Consumer defines "expected request and response"; Provider verifies it satisfies that contract. Reduces Provider breaking Consumer by surprise.
  • Testing: Consumer uses a mock Provider to verify request construction and response parsing; Provider uses the contract to verify its implementation. If both pass, integration is more likely to succeed.

Example

Example 1: Flow

Plain text
Consumer defines contract (Pact file) → local test with mock
Provider loads contract → verifies implementation satisfies it
Both pass → lower integration risk after deploy

Example 2: Pact example (conceptual)

  • Consumer: Expects GET /user/1 to return {id:1, name:"..."}. Generates pact file.
  • Provider: Loads pact, calls /user/1, checks response matches pact.

Example 3: Contract vs integration test

TypeCharacteristics
ContractLightweight, no real deploy; validates format and agreement
IntegrationReal calls; validates end-to-end; slower, env-dependent
  • Contract tests do not replace integration tests but can catch interface mismatches earlier.

Example 4: Consumer Pact (simplified)

Java
// Consumer test
@PactTestFor(providerName = "user-service")
void testGetUser(PactVerificationContext context) {
    context.verifyInteraction();
}

Core Mechanism / Behavior

  • Consumer test: Stub Provider; Consumer builds request and parses response; generates pact file.
  • Provider test: Provider starts; pact verifier calls endpoints; compares response to pact.
  • Contract as artifact: Pact file is versioned and shared; CI runs both consumer and provider tests.

Key Rules

  • Consumer-driven: Consumer defines expectations; Provider fulfills them; reduces unilateral Provider changes.
  • Version the contract and align with service version; update contract first, then implement.
  • Run in CI; both sides run contract tests; contract changes require agreement.

What's Next

See Service Versioning, API Gateway. See Distributed Tracing for cross-service call verification.