mcpField
A
api-contract-testing

api-contract-testing

github.com/secondsky测试与质量240483 次安装5 周前更新
代码仓库

关于 api-contract-testing

用于验证 API 是否符合消费者与提供方约定的测试技能,涵盖 Pact 消费者驱动测试、提供方验证和 OpenAPI 模式校验。

主要功能

  1. 01消费者驱动的 Pact 测试
  2. 02提供方验证
  3. 03OpenAPI 请求与响应校验
  4. 04多种语言生态的实践指南

适用场景

  1. 01检查依赖服务间的 API 约定
  2. 02根据已发布契约验证提供方行为
  3. 03按 OpenAPI 校验 Express 请求与响应

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/secondsky/claude-skills --skill api-contract-testing

安装后在 Claude Code 中输入/api-contract-testing确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
java-rest-assured.md
pact-broker-cicd.md
python-json-schema.md

详细介绍

API 契约测试

验证 API 是否遵守消费者与提供者之间的契约,无需进行完整的集成测试。

核心概念

术语定义
消费者调用 API 的服务
提供者提供 API 的服务
契约双方约定的请求/响应格式
Pact消费者驱动的契约测试工具
架构结构定义(OpenAPI、JSON Schema)
Broker契约的中央存储库

Pact 消费者测试(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('[email protected]')
        })
      })
      .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);
      });
  });
});

提供者验证

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 验证(Express)

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

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

其他实现

最佳实践

应该:

  • 从消费者的角度进行测试
  • 使用匹配器实现灵活匹配
  • 验证结构,而非特定值
  • 明确对契约进行版本控制
  • 测试错误响应
  • 在 CI 流水线中运行测试
  • 测试向后兼容性

不应该:

  • 在契约中测试业务逻辑
  • 对特定值进行硬编码
  • 跳过错误场景
  • 忽略版本控制
  • 未经验证就部署

工具

  • Pact - 多语言消费者驱动契约
  • Spring Cloud Contract - JVM 生态系统
  • OpenAPI/Swagger - 以架构为先的验证
  • Dredd - API Blueprint 测试
  • Spectral - OpenAPI lint 工具

评论

支持 Markdown