Get the FREE Ultimate OpenClaw Setup Guide →

api-contract-testing

Scanned
npx machina-cli add skill secondsky/claude-skills/api-contract-testing --openclaw
Files (1)
SKILL.md
3.8 KB

API Contract Testing

Verify that APIs honor their contracts between consumers and providers without requiring full integration tests.

Key Concepts

TermDefinition
ConsumerService that calls an API
ProviderService that exposes an API
ContractAgreed request/response format
PactConsumer-driven contract testing tool
SchemaStructure definition (OpenAPI, JSON Schema)
BrokerCentral repository for contracts

Pact Consumer Test (TypeScript)

import { PactV3, MatchersV3 } from '@pact-foundation/pact';

const provider = new PactV3({
  consumer: 'OrderService',
  provider: 'UserService'
});

describe('User API Contract', () => {
  it('returns user by ID', async () => {
    await provider
      .given('user 123 exists')
      .uponReceiving('a request for user 123')
      .withRequest({ method: 'GET', path: '/users/123' })
      .willRespondWith({
        status: 200,
        body: MatchersV3.like({
          id: '123',
          name: MatchersV3.string('John'),
          email: MatchersV3.email('john@example.com')
        })
      })
      .executeTest(async (mockServer) => {
        const response = await fetch(`${mockServer.url}/users/123`);
        expect(response.status).toBe(200);
      });
  });

  it('returns 404 for non-existent user', async () => {
    await provider
      .given('user does not exist')
      .uponReceiving('a request for non-existent user')
      .withRequest({ method: 'GET', path: '/users/999' })
      .willRespondWith({
        status: 404,
        body: MatchersV3.like({
          error: { code: 'NOT_FOUND', message: MatchersV3.string() }
        })
      })
      .executeTest(async (mockServer) => {
        const response = await fetch(`${mockServer.url}/users/999`);
        expect(response.status).toBe(404);
      });
  });
});

Provider Verification

import { Verifier } from '@pact-foundation/pact';

new Verifier({
  provider: 'UserService',
  providerBaseUrl: 'http://localhost:3000',
  pactBrokerUrl: process.env.PACT_BROKER_URL,
  publishVerificationResult: true,
  providerVersion: process.env.GIT_SHA,
  stateHandlers: {
    'user 123 exists': async () => {
      await db.users.create({ id: '123', name: 'John' });
    },
    'user does not exist': async () => {
      await db.users.deleteAll();
    }
  }
}).verifyProvider();

OpenAPI Validation (Express)

const OpenApiValidator = require('express-openapi-validator');

app.use(OpenApiValidator.middleware({
  apiSpec: './openapi.yaml',
  validateRequests: true,
  validateResponses: true,
  validateSecurity: true
}));

Additional Implementations

Best Practices

Do:

  • Test from consumer perspective
  • Use matchers for flexible matching
  • Validate structure, not specific values
  • Version contracts explicitly
  • Test error responses
  • Run tests in CI pipeline
  • Test backward compatibility

Don't:

  • Test business logic in contracts
  • Hard-code specific values
  • Skip error scenarios
  • Ignore versioning
  • Deploy without verification

Tools

  • Pact - Multi-language consumer-driven contracts
  • Spring Cloud Contract - JVM ecosystem
  • OpenAPI/Swagger - Schema-first validation
  • Dredd - API blueprint testing
  • Spectral - OpenAPI linting

Source

git clone https://github.com/secondsky/claude-skills/blob/main/plugins/api-contract-testing/skills/api-contract-testing/SKILL.mdView on GitHub

Overview

API Contract Testing verifies that APIs honor contracts between consumers and providers without requiring full integration tests. It centers on consumer-driven contracts, schema validation, and tools like Pact to prevent breaking changes and validate OpenAPI specs.

How This Skill Works

Developers author consumer-driven contracts using Pact, describing expected requests and responses. Providers verify against those contracts via provider verification and publish results to a Pact Broker, enabling cross-service compatibility and OpenAPI schema validation.

When to Use It

  • Testing microservices communication to ensure contract adherence
  • Preventing breaking changes when APIs evolve
  • Validating OpenAPI specifications and JSON schemas
  • Integrating contract tests into CI/CD pipelines
  • Verifying provider implementations against consumer expectations via Pact Broker

Quick Start

  1. Step 1: Create a Pact consumer test describing expected requests/responses (e.g., GET /users/{id} → 200 with id, name, email)
  2. Step 2: Run provider verification against the provider base URL and publish results to a Pact Broker
  3. Step 3: (Optional) Add OpenAPI validation in your Express app to enforce the API schema at runtime

Best Practices

  • Test from the consumer perspective using real scenarios
  • Use matchers for flexible value validation
  • Validate structure, not exact values
  • Version contracts explicitly to manage changes
  • Run contract tests in CI/CD and verify backward compatibility

Example Use Cases

  • A microservice pair (OrderService and UserService) validates contracts with Pact consumer tests
  • Provider verification checks a running UserService against consumer contracts and publishes results to a Pact Broker
  • OpenAPI validation added to an Express app using express-openapi-validator to enforce API schemas
  • CI/CD pipelines run pact:verify and publish outcomes to Pact Broker for traceability
  • Cross-language contracts via Pact across Node, Java, and Python services

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers