contract-testing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseContract Testing
契约测试
<default_to_action>
When testing API contracts or microservices:
- DEFINE consumer expectations (what consumers actually need)
- VERIFY provider fulfills contracts (Pact verification)
- DETECT breaking changes before deployment (CI/CD integration)
- VERSION APIs semantically (breaking = major bump)
- MAINTAIN backward compatibility for supported versions
Quick Contract Testing Steps:
- Consumer: Define expected request/response pairs
- Provider: Verify against all consumer contracts
- CI/CD: Block deploys that break contracts
- Versioning: Document supported versions and deprecation
Critical Success Factors:
- Consumers own the contract (they define what they need)
- Provider must pass all consumer contracts before deploy
- Breaking changes require coordination, not surprise </default_to_action>
<default_to_action>
在测试API契约或微服务时:
- 定义消费者期望(即消费者实际的需求)
- 验证提供者是否满足契约(Pact验证)
- 在部署前检测破坏性变更(CI/CD集成)
- 对API进行语义化版本控制(破坏性变更=主版本号升级)
- 为受支持的版本维护向后兼容性
快速契约测试步骤:
- 消费者:定义预期的请求/响应对
- 提供者:针对所有消费者契约进行验证
- CI/CD:阻止会破坏契约的部署
- 版本控制:记录受支持的版本和弃用信息
关键成功因素:
- 消费者主导契约(由他们定义自身需求)
- 提供者在部署前必须通过所有消费者契约验证
- 破坏性变更需要提前协调,而非突然实施 </default_to_action>
Quick Reference Card
快速参考卡片
When to Use
适用场景
- Microservices communication
- Third-party API integrations
- Distributed team coordination
- Preventing breaking changes
- 微服务通信
- 第三方API集成
- 分布式团队协调
- 预防破坏性变更
Consumer-Driven Contract Flow
消费者驱动契约流程
Consumer → Defines Expectations → Contract
↓
Provider → Verifies Contract → Pass/Fail
↓
CI/CD → Blocks Breaking ChangesConsumer → Defines Expectations → Contract
↓
Provider → Verifies Contract → Pass/Fail
↓
CI/CD → Blocks Breaking ChangesBreaking vs Non-Breaking Changes
破坏性与非破坏性变更对比
| Change Type | Breaking? | Semver |
|---|---|---|
| Remove field | ✅ Yes | Major |
| Rename field | ✅ Yes | Major |
| Change type | ✅ Yes | Major |
| Add optional field | ❌ No | Minor |
| Add new endpoint | ❌ No | Minor |
| Bug fix | ❌ No | Patch |
| 变更类型 | 是否具有破坏性? | 语义化版本(Semver) |
|---|---|---|
| 删除字段 | ✅ 是 | 主版本 |
| 重名字段 | ✅ 是 | 主版本 |
| 变更类型 | ✅ 是 | 主版本 |
| 添加可选字段 | ❌ 否 | 次版本 |
| 添加新端点 | ❌ 否 | 次版本 |
| Bug修复 | ❌ 否 | 修订版本 |
Tools
工具推荐
| Tool | Best For |
|---|---|
| Pact | Consumer-driven contracts |
| OpenAPI/Swagger | API-first design |
| JSON Schema | Schema validation |
| GraphQL | Schema-first contracts |
| 工具 | 最佳适用场景 |
|---|---|
| Pact | 消费者驱动契约 |
| OpenAPI/Swagger | API优先设计 |
| JSON Schema | 模式验证 |
| GraphQL | 模式优先契约 |
Consumer Contract (Pact)
消费者契约(Pact)
javascript
// Consumer defines what it needs
const { Pact } = require('@pact-foundation/pact');
describe('Order API Consumer', () => {
const provider = new Pact({
consumer: 'CheckoutUI',
provider: 'OrderService'
});
beforeAll(() => provider.setup());
afterAll(() => provider.finalize());
it('creates an order', async () => {
await provider.addInteraction({
state: 'products exist',
uponReceiving: 'a create order request',
withRequest: {
method: 'POST',
path: '/orders',
body: { productId: 'abc', quantity: 2 }
},
willRespondWith: {
status: 201,
body: {
orderId: like('order-123'), // Any string matching pattern
total: like(19.99) // Any number
}
}
});
const response = await orderClient.create({ productId: 'abc', quantity: 2 });
expect(response.orderId).toBeDefined();
});
});javascript
// Consumer defines what it needs
const { Pact } = require('@pact-foundation/pact');
describe('Order API Consumer', () => {
const provider = new Pact({
consumer: 'CheckoutUI',
provider: 'OrderService'
});
beforeAll(() => provider.setup());
afterAll(() => provider.finalize());
it('creates an order', async () => {
await provider.addInteraction({
state: 'products exist',
uponReceiving: 'a create order request',
withRequest: {
method: 'POST',
path: '/orders',
body: { productId: 'abc', quantity: 2 }
},
willRespondWith: {
status: 201,
body: {
orderId: like('order-123'), // Any string matching pattern
total: like(19.99) // Any number
}
}
});
const response = await orderClient.create({ productId: 'abc', quantity: 2 });
expect(response.orderId).toBeDefined();
});
});Provider Verification
提供者验证
javascript
// Provider verifies it fulfills all consumer contracts
const { Verifier } = require('@pact-foundation/pact');
describe('Order Service Provider', () => {
it('fulfills all consumer contracts', async () => {
await new Verifier({
provider: 'OrderService',
providerBaseUrl: 'http://localhost:3000',
pactUrls: ['./pacts/checkoutui-orderservice.json'],
stateHandlers: {
'products exist': async () => {
await db.products.create({ id: 'abc', price: 9.99 });
}
}
}).verifyProvider();
});
});javascript
// Provider verifies it fulfills all consumer contracts
const { Verifier } = require('@pact-foundation/pact');
describe('Order Service Provider', () => {
it('fulfills all consumer contracts', async () => {
await new Verifier({
provider: 'OrderService',
providerBaseUrl: 'http://localhost:3000',
pactUrls: ['./pacts/checkoutui-orderservice.json'],
stateHandlers: {
'products exist': async () => {
await db.products.create({ id: 'abc', price: 9.99 });
}
}
}).verifyProvider();
});
});Breaking Change Detection
破坏性变更检测
typescript
// Agent detects breaking changes
await Task("Contract Validation", {
currentContract: 'openapi-v2.yaml',
previousContract: 'openapi-v1.yaml',
detectBreaking: true,
calculateSemver: true,
generateMigrationGuide: true
}, "qe-api-contract-validator");
// Output:
// Breaking changes found: 2
// - Removed field: order.discount
// - Type change: order.total (number → string)
// Recommended version: 3.0.0 (major bump)typescript
// Agent detects breaking changes
await Task("Contract Validation", {
currentContract: 'openapi-v2.yaml',
previousContract: 'openapi-v1.yaml',
detectBreaking: true,
calculateSemver: true,
generateMigrationGuide: true
}, "qe-api-contract-validator");
// Output:
// Breaking changes found: 2
// - Removed field: order.discount
// - Type change: order.total (number → string)
// Recommended version: 3.0.0 (major bump)CI/CD Integration
CI/CD集成
yaml
name: Contract Tests
on: [push]
jobs:
consumer-tests:
steps:
- run: npm run test:contract
- name: Publish Pacts
run: npx pact-broker publish ./pacts --broker-base-url $PACT_BROKER
provider-verification:
needs: consumer-tests
steps:
- name: Verify Provider
run: npm run verify:contracts
- name: Can I Deploy?
run: npx pact-broker can-i-deploy --pacticipant OrderService --version $VERSIONyaml
name: Contract Tests
on: [push]
jobs:
consumer-tests:
steps:
- run: npm run test:contract
- name: Publish Pacts
run: npx pact-broker publish ./pacts --broker-base-url $PACT_BROKER
provider-verification:
needs: consumer-tests
steps:
- name: Verify Provider
run: npm run verify:contracts
- name: Can I Deploy?
run: npx pact-broker can-i-deploy --pacticipant OrderService --version $VERSIONAgent Coordination Hints
Agent协调提示
Memory Namespace
内存命名空间
aqe/contract-testing/
├── contracts/* - Current contracts
├── breaking-changes/* - Detected breaking changes
├── versioning/* - Version compatibility matrix
└── verification-results/* - Provider verification historyaqe/contract-testing/
├── contracts/* - Current contracts
├── breaking-changes/* - Detected breaking changes
├── versioning/* - Version compatibility matrix
└── verification-results/* - Provider verification historyFleet Coordination
集群协调
typescript
const contractFleet = await FleetManager.coordinate({
strategy: 'contract-testing',
agents: [
'qe-api-contract-validator', // Validation, breaking detection
'qe-test-generator', // Generate contract tests
'qe-security-scanner' // API security
],
topology: 'sequential'
});typescript
const contractFleet = await FleetManager.coordinate({
strategy: 'contract-testing',
agents: [
'qe-api-contract-validator', // Validation, breaking detection
'qe-test-generator', // Generate contract tests
'qe-security-scanner' // API security
],
topology: 'sequential'
});Related Skills
相关技能
- api-testing-patterns - API testing strategies
- shift-left-testing - Early contract validation
- cicd-pipeline-qe-orchestrator - Pipeline integration
- api-testing-patterns - API测试策略
- shift-left-testing - 早期契约验证
- cicd-pipeline-qe-orchestrator - 流水线集成
Remember
注意事项
Consumers own the contract. They define what they need; providers must fulfill it. Breaking changes require major version bumps and coordination. CI/CD blocks deploys that break contracts. Use Pact for consumer-driven, OpenAPI for API-first.
With Agents: Agents validate contracts, detect breaking changes with semver recommendations, and generate migration guides. Use agents to maintain contract compliance at scale.
消费者主导契约。由消费者定义自身需求,提供者必须满足这些需求。破坏性变更需要升级主版本号并提前协调。CI/CD会阻止破坏契约的部署。消费者驱动场景使用Pact,API优先场景使用OpenAPI。
借助Agent: Agent可验证契约、检测破坏性变更并提供语义化版本(Semver)建议,还能生成迁移指南。使用Agent可大规模维护契约合规性。