关于 api-testing-patterns
api-testing-patterns 是一套 API 测试策略与模式指南,面向测试人员和 API 开发团队。内容覆盖契约、组件和集成测试,并强调从消费者角度验证行为与错误处理。
主要功能
- 01选择契约、组件或集成测试
- 02按消费者视角验证 API 契约
- 03覆盖认证、输入与错误场景
- 04测试幂等性和并发行为
- 05从 OpenAPI 规范生成测试
适用场景
- 01设计 REST 或 GraphQL API 测试策略
- 02验证微服务间的消费者契约
- 03在 CI/CD 中防止 API 变更破坏兼容性
- 04检查关键端点的负载表现
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ proffesor-for-testing/ agentic-qe --skill api-testing-patterns安装后在 Claude Code 中输入/api-testing-patterns确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
config.jsonevals/api-testing-patterns.yamlschemas/output.jsonscripts/validate-config.jsontemplates/api-test-scaffold.md详细介绍
API 测试模式
<default_to_action> 测试 API 或设计 API 测试策略时:
- 确定测试级别:契约、集成或组件
- 测试契约,而非实现(从消费者视角出发)
- 验证身份验证、输入、错误、幂等性和并发
- 在 CI/CD 中使用架构验证实现自动化
- 监控生产环境中的 API,发现契约漂移
快速选择模式:
- 微服务 → 消费者驱动契约(Pact)
- REST API → CRUD + 分页 + 筛选测试
- GraphQL → 查询验证 + 复杂度限制
- 外部依赖 → 使用组件测试进行模拟
- 性能 → 对关键端点进行负载测试
关键成功因素:
- API 是契约——应从消费者视角进行测试
- 始终测试错误场景,而不只是成功路径
- 对 API 测试进行版本控制,防止破坏性变更 </default_to_action>
快速参考卡
适用场景
- 测试 REST 或 GraphQL API
- 验证微服务契约
- 设计 API 测试策略
- 防止 API 发生破坏性变更
测试级别
| 级别 | 目的 | 依赖项 | 速度 |
|---|---|---|---|
| 契约 | 提供方与消费者达成一致 | 无 | 快 |
| 组件 | 隔离测试 API | 模拟对象 | 快 |
| 集成 | 使用真实依赖项 | 数据库、服务 | 较慢 |
关键测试场景
| 场景 | 必须测试 | 示例 |
|---|---|---|
| 身份验证 | 401/403 处理 | 令牌过期、用户错误 |
| 输入 | 400 验证 | 缺少字段、类型错误 |
| 错误 | 妥善处理 500 错误 | 数据库宕机、超时 |
| 幂等性 | 防止重复操作 | 使用相同的幂等键 |
| 并发 | 竞态条件 | 并行结账 |
工具
- 契约:Pact、Spring Cloud Contract
- REST:Supertest、REST-assured、Playwright
- 负载:k6、Artillery、JMeter
Agent 协作
qe-api-contract-validator:验证契约,检测破坏性变更qe-test-generator:根据 OpenAPI 规范生成测试qe-performance-tester:对端点进行负载测试qe-security-scanner:API 安全测试
契约测试
模式:消费者驱动契约
// Consumer defines expectations
const contract = {
request: { method: 'POST', path: '/orders', body: { productId: 'abc', quantity: 2 } },
response: { status: 201, body: { orderId: 'string', total: 'number' } }
};
// Provider must fulfill
test('order API meets contract', async () => {
const response = await api.post('/orders', { productId: 'abc', quantity: 2 });
expect(response.status).toBe(201);
expect(response.body).toMatchSchema({
orderId: expect.any(String),
total: expect.any(Number)
});
});
适用场景: 微服务、分布式系统、第三方集成
关键测试模式
身份验证与授权
describe('Auth', () => {
it('rejects without token', async () => {
expect((await api.get('/orders')).status).toBe(401);
});
it('rejects expired token', async () => {
const expired = generateExpiredToken();
expect((await api.get('/orders', { headers: { Authorization: `Bearer ${expired}` } })).status).toBe(401);
});
it('blocks cross-user access', async () => {
const userAToken = generateToken({ userId: 'A' });
expect((await api.get('/orders/user-B-order', { headers: { Authorization: `Bearer ${userAToken}` } })).status).toBe(403);
});
});
输入验证
describe('Validation', () => {
it('validates required fields', async () => {
const response = await api.post('/orders', { quantity: 2 }); // Missing productId
expect(response.status).toBe(400);
expect(response.body.errors).toContain('productId is required');
});
it('validates types', async () => {
expect((await api.post('/orders', { productId: 'abc', quantity: 'two' })).status).toBe(400);
});
it('validates ranges', async () => {
expect((await api.post('/orders', { productId: 'abc', quantity: -5 })).status).toBe(400);
});
});
幂等性
it('prevents duplicates with idempotency key', async () => {
const key = 'unique-123';
const data = { productId: 'abc', quantity: 2 };
const r1 = await api.post('/orders', data, { headers: { 'Idempotency-Key': key } });
const r2 = await api.post('/orders', data, { headers: { 'Idempotency-Key': key } });
expect(r1.body.orderId).toBe(r2.body.orderId); // Same order
});
并发
it('handles race condition on inventory', async () => {
const promises = Array(10).fill().map(() =>
api.post('/orders', { productId: 'abc', quantity: 1 })
);
const responses = await Promise.all(promises);
const successful = responses.filter(r => r.status === 201);
const inventory = await db.inventory.findById('abc');
expect(inventory.quantity).toBe(initialQuantity - successful.length);
});
REST CRUD 模式
describe('Product CRUD', () => {
let productId;
it('CREATE', async () => {
const r = await api.post('/products', { name: 'Widget', price: 10 });
expect(r.status).toBe(201);
productId = r.body.id;
});
it('READ', async () => {
const r = await api.get(`/products/${productId}`);
expect(r.body.name).toBe('Widget');
});
it('UPDATE', async () => {
const r = await api.put(`/products/${productId}`, { price: 12 });
expect(r.body.price).toBe(12);
});
it('DELETE', async () => {
expect((await api.delete(`/products/${productId}`)).status).toBe(204);
expect((await api.get(`/products/${productId}`)).status).toBe(404);
});
});
最佳实践
✅ 推荐做法
- 从消费者视角进行测试
- 使用架构验证(而非精确值)
- 全面测试错误场景
- 对 API 测试进行版本控制
- 在 CI/CD 中实现自动化
❌ 应避免
- 测试实现,而非契约
- 忽略 HTTP 语义(状态码)
- 不进行负向测试
- 断言字段顺序或额外字段
- 测试速度过慢(模拟外部服务)
Agent 辅助 API 测试
// Validate contracts
await Task("Contract Validation", {
spec: 'openapi.yaml',
endpoint: '/orders',
checkBreakingChanges: true
}, "qe-api-contract-validator");
// Generate tests from spec
await Task("Generate API Tests", {
spec: 'openapi.yaml',
coverage: 'comprehensive',
include: ['happy-paths', 'input-validation', 'auth-scenarios', 'error-handling']
}, "qe-test-generator");
// Load test
await Task("API Load Test", {
endpoint: '/orders',
rps: 1000,
duration: '5min'
}, "qe-performance-tester");
// Security scan
await Task("API Security Scan", {
spec: 'openapi.yaml',
checks: ['sql-injection', 'xss', 'broken-auth', 'rate-limiting']
}, "qe-security-scanner");
Agent 协作提示
记忆命名空间
aqe/api-testing/
├── contracts/* - API contract definitions
├── generated-tests/* - Generated test suites
├── validation/* - Contract validation results
└── performance/* - Load test results
Fleet 协作
const apiFleet = await FleetManager.coordinate({
strategy: 'contract-testing',
agents: ['qe-api-contract-validator', 'qe-test-generator', 'qe-test-executor'],
topology: 'mesh'
});
await apiFleet.execute({
services: [
{ name: 'orders-api', consumers: ['checkout-ui', 'admin-api'] },
{ name: 'payment-api', consumers: ['orders-api'] }
]
});
相关技能
- agentic-quality-engineering - 使用 Agent 进行 API 测试
- tdd-london-chicago - API 测试的伦敦学派
- performance-testing - API 负载测试
- security-testing - API 安全验证
- contract-testing - 深入了解消费者驱动契约
请记住
API 测试 = 验证契约和行为,而非实现。关注消费者在意的方面:正确的响应、妥善的错误处理、可接受的性能。
使用 Agent: Agent 可自动验证契约、根据规范生成全面的测试套件,并监控生产环境中的 API,发现契约漂移。使用 Agent 大规模维护 API 质量。
注意事项
- Agent 会根据文档中的 API 生成测试,而非实际 API——始终先对运行中的服务进行验证
- 身份验证令牌会在测试运行之间过期——使用包含长期有效令牌的 fixture,或在每个测试套件运行前刷新令牌
- CI 中的速率限制会导致间歇性故障——对 429 响应添加指数退避重试
- 生产环境中可能已禁用 GraphQL 自省——使用暂存环境的架构进行测试,而非生产端点
- 幂等性测试需要为每次运行使用唯一的请求 ID——硬编码 ID 会导致重试时误判为通过
评论
支持 Markdown