contract-testing について
contract-testingは、APIやマイクロサービスの契約テストを支援するスキルです。コンシューマーの期待定義、プロバイダー検証、デプロイ前の変更確認を扱い、実際の利用要件に基づく契約とセマンティックバージョニング、CI/CDによる破壊的変更の検出を重視します。
主な機能
- 01コンシューマー主導の契約を定義
- 02プロバイダーの契約適合性を検証
- 03APIの破壊的変更を検出
- 04セマンティックバージョニングでAPIを管理
- 05CI/CDで非互換なデプロイを阻止
活用シーン
- 01マイクロサービス間の契約をテスト
- 02サードパーティAPI連携を検証
- 03分散チーム間のインターフェース変更を調整
- 04デプロイ前に非互換な変更を検出
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ proffesor-for-testing/ agentic-qe --skill contract-testingインストール後、Claude Code で/contract-testingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
config.jsonevals/contract-testing.yamlreferences/agent-commands.mdprovider-states.mdschemas/output.jsonscripts/validate-config.json詳細
コントラクトテスト
<default_to_action> API コントラクトやマイクロサービスをテストする場合:
- コンシューマーの期待値を定義する(コンシューマーが実際に必要としているもの)
- プロバイダーがコントラクトを満たしていることを検証する(Pact の検証)
- デプロイ前に破壊的変更を検出する(CI/CD との統合)
- API をセマンティックバージョニングする(破壊的変更=メジャーバージョンの更新)
- サポート対象バージョンの後方互換性を維持する
コントラクトテストの簡単な手順:
- コンシューマー:期待するリクエスト/レスポンスの組み合わせを定義する
- プロバイダー:すべてのコンシューマーコントラクトに照らして検証する
- CI/CD:コントラクトを破壊するデプロイをブロックする
- バージョニング:サポート対象バージョンと非推奨化を文書化する
成功のための重要な要素:
- コントラクトの所有者はコンシューマーです(必要なものを定義します)
- プロバイダーはデプロイ前に、すべてのコンシューマーコントラクトに合格する必要があります
- 破壊的変更には、予告なしではなく、調整が必要です </default_to_action>
クイックリファレンスカード
使用する場面
- マイクロサービス間の通信
- サードパーティ API との統合
- 分散チーム間の連携
- 破壊的変更の防止
コンシューマー主導のコントラクトの流れ
Consumer → Defines Expectations → Contract
↓
Provider → Verifies Contract → Pass/Fail
↓
CI/CD → Blocks Breaking Changes
破壊的変更と非破壊的変更
| 変更の種類 | 破壊的か | Semver |
|---|---|---|
| フィールドの削除 | ✅ はい | メジャー |
| フィールド名の変更 | ✅ はい | メジャー |
| 型の変更 | ✅ はい | メジャー |
| 任意フィールドの追加 | ❌ いいえ | マイナー |
| 新しいエンドポイントの追加 | ❌ いいえ | マイナー |
| バグ修正 | ❌ いいえ | パッチ |
ツール
| ツール | 最適な用途 |
|---|---|
| Pact | コンシューマー主導のコントラクト |
| OpenAPI/Swagger | API ファーストの設計 |
| JSON Schema | スキーマの検証 |
| GraphQL | スキーマファーストのコントラクト |
コンシューマーコントラクト(Pact)
// 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 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();
});
});
破壊的変更の検出
// 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 との統合
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 $VERSION
エージェント連携のヒント
メモリの名前空間
aqe/contract-testing/
├── contracts/* - Current contracts
├── breaking-changes/* - Detected breaking changes
├── versioning/* - Version compatibility matrix
└── verification-results/* - Provider verification history
フリート連携
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'
});
エージェント CLI と高度なパターン
v3 エージェント固有のコマンド(aqe contract ...)、GraphQL コントラクト、イベントコントラクト、Pact Broker との統合については、references/agent-commands.md を参照してください。
関連スキル
- api-testing-patterns - API テスト戦略
- shift-left-testing - 早期のコントラクト検証
- cicd-pipeline-qe-orchestrator - パイプラインとの統合
覚えておくこと
コントラクトの所有者はコンシューマーです。 コンシューマーが必要なものを定義し、プロバイダーはそれを満たす必要があります。破壊的変更には、メジャーバージョンの更新と調整が必要です。CI/CD はコントラクトを破壊するデプロイをブロックします。コンシューマー主導には Pact、API ファーストには OpenAPI を使用してください。
エージェントを使う場合: エージェントはコントラクトを検証し、Semver に基づく推奨とともに破壊的変更を検出し、移行ガイドを生成します。エージェントを活用して、大規模にコントラクトへの準拠を維持してください。
注意点
- 実行前に Pact Broker の URL を設定する必要があります。設定しないと、エージェントは検証を黙ってスキップするテストを生成します
- プロバイダーの状態が設定されていないと、コンシューマーテストがローカルでは成功しても CI では失敗します。必ず両側を検証してください
- レスポンスに必須フィールドを追加するのは、プロバイダーテストが成功しても破壊的変更です。コンシューマーはそのフィールドを想定していません
- エージェントは実際のコンシューマーの利用状況ではなく、API ドキュメントからコントラクトを生成する場合があります。コントラクトには実際のコンシューマーのニーズを反映させる必要があります
- GraphQL のコントラクトテストでは、スキーマのスティッチングを考慮する必要があります。フラグメントが他のサービスの型を参照する場合があります
コメント
Markdown 対応