API契約テスト
1)なぜ契約テストをするか
契約は、顧客の期待とプロバイダの約束をキャプチャします:ルート/メソッド、ヘッダー、ボディスキーマ、ステータス、エラーセマンティクス、制約。目標は、統合前に互換性のない変更をキャッチし、重いE2Eなしで安全にバージョンをリリースすることです。
2)アプローチ
消費者主導の契約(CDC):クライアントは期待を形成します(協定とアナログ);プロバイダは定期的にそれらを検証します。
仕様:単一の真実のソースとしての契約(OpenAPI/Protobuf/GraphQL SDL);テストは仕様に対して実装を検証します。
イベントベース:メッセージスキーマ(Avro/JSON Schema/Protobuf)+ブローカー/レジストリ互換性ルール。
3) HTTP/REST仕様ストリーム
1.契約:OpenAPI 3。x(図、例、コード)。
2.Lintおよびstat解析:スタイル、必須フィールド、ユニフォームコード。
3.実装検証:anti-OpenAPIテストジェネレータ(schemathesis/Dreddアプローチ)+手動ネガ。
4.スナップショット:サンプルレスポンス、ETagセマンティクス、idempotencyヘッダーをキャプチャします。
yaml paths:
/v1/payments:
post:
responses:
"201": { $ref: "#/components/responses/PaymentCreated" }
"409": { description: Duplicate by Idempotency-Key }
"422": { description: Schema/Business validation failed }
4) CDC(協定アプローチ)
ライフサイクル:1.消費者はテストを書き込み、pactファイル(期待値)を生成します。
2.ブローカーでの出版(アーティファクト)。
3.CIのプロバイダはサービス(または契約ラック)を調達し、pactを検証します。
4.ブローカーは、can-i-deploy互換性マトリックスを計算します。
消費者テスト(擬似JS)の例:js pact
.given("wallet exists")
.uponReceiving("get wallet")
.withRequest({ method:"GET", path:"/v1/wallets/w123", headers:{ "Authorization": term({generate:"Bearer x", matcher:/^Bearer\s.+/}) }})
.willRespondWith({
status: 200,
headers: { "Content-Type": "application/json" },
body: like({ id:"w123", currency: "EUR", balance: 0 })
});
5) gRPC/Protobuf契約
契約はパッケージ/サービスバージョンで'。proto'です。
互換性:タグを再利用しないでください、オプションで新しいものを追加するだけ、使用されているフィールドを削除しないでください。数を予約してください。
テスト:サーバ/クライアントのスタブ生成、自動生成ケースレンタル+ネガ(不明なフィールド、サイズ制限)。
6)イベント契約(Kafka/NATS/……)
Схемы: Avro/JSON スキーマ/Protobufスキーマレジストリ。
互換性ポリシーは'BACKWARD'(多くの場合十分)または'FULL'です。
プロデューサーのテスト:メッセージをスキームに対して検証します。消費者テスト:古いバージョンと新しいバージョンを受け入れます。
不変量:idempotenceキー、order/repeatability、重複除外セマンティクス。
json
{"type":"record","name":"PayoutCreated","fields":[
{"name":"payoutId","type":"string"},
{"name":"amount","type":"double"},
{"name":"currency","type":{"type":"string","logicalType":"iso-4217"}}
]}
7)互換性とバージョン
下位互換性(推奨最小):オプションフィールドを追加し、既存のフィールドを破棄しないでください。
前方互換性:消費者は未知のフィールドを無視します。
フル:両方。
バージョン管理:'path (/v1)'、 'Accept: application/vnd。ブランド。v2+json'、'proto package v2'。
偏差ポリシー:出力ウィンドウ(例えば、90日)、警告ヘッダ/イベント。
8)否定的なおよび間違いはまた契約です
コードの標準化:400/401/403/404/409/422/429/5xx、必須フィールド'code'、 'message'、 'trace_id'。
サイズ/限度は契約(413/414/431)の一部です。
Idempotency:反復動作(409対201同じid)。
カテゴリー:'Retry-After' at 429/503、 'Idempotency-Key'、 'Content-Language'など。
json
{ "code":"validation_error", "message":"amount must be ≥ 1", "trace_id":"..." }
9)契約により管理されるデータ
例-ライブ、CIで検証。
CDCのための据え付け品は最低、決定論的です。
データ生成-数値/日付のプロパティベース。スナップショットの安定性を損なうことはありません。
10) CI/CDのパイプライン(参照)
1.Lint/validate: OpenAPI/Proto/Avro ('validate'、 style-knowledge)。
2.公開:アーティファクト(ブローカー/レジストリ)としての契約。
3.検証:プロバイダはCDCパケット/仕様テストを実行します。
4.can-i-deploy gate:グリーンマトリックスなしでのリリースは許可されません。
5.Diff-変更が意味diffであることを確認します。
6.レポート:JUnit/HTML、違反/定義のリスト。
yaml jobs:
lint:...
publish-contract: needs: [lint]
verify-provider: needs: [publish-contract]
can-i-deploy:
if: always()
steps: [run: pact-broker can-i-deploy...]
11)ツール(タスククラス別)
Lint/validators: openapi-linters、 protobuf-lint、 avro-tools。
CDC: Pactファミリー/ブローカー、Spring Cloud Contract、 Hoverfly (HTTPレコード/リプレイ)。
仕様ランナー:schemathesis/Dredd-likeアプローチ、Postman test+JSONスキーマ。
Diff: semantic-diff OpenAPI/Proto/Avro(変更の破損を検出)。
コンテナ:プロバイダ/契約デスクを調達するためのテストコンテナ。
12) Antipatterns
コード→非同期化とは別に「Special dock」。サービスの近くに契約を保管してください。
契約の代わりにサードパーティのサービスのモキ→更新中の脆弱性。
→フレーク方式に結合せずにランダムな応答/生成を行います。
バージョンなしでタイプ/必須フィールドを変更します。
通知/削除なしのサイレント拡張。
負の契約とエラーコードはありません。
13) iGaming/Financeの詳細
マネーフィールドの形式化:'amount'-スケール、通貨-ISO-4217、金額の不変量の小数。
支払/webhook契約:HMAC/mTLS、アンチリプレイ('X-Timestamp'ウィンドウ)、idempotency、 'Retry-After'。
地域/テナント:必須ヘッダー'X-Tenant/X-Region'、メッセージのローカライズ。
イベント:変更されていないログ(監査)、重複除外キー、配信保証(少なくとも一度+idempotentハンドラ)。
14)テストの「骨格」の例
14.1 Schemathesis-style(擬似)
bash schemathesis run openapi. yaml --checks all --hypothesis-deadline=200
14.2スペックランナーとしてのポストマン
js pm. test ("Scheme/v1/wallets/{ id} is valid," () => {
const schema = pm. collectionVariables. get("wallet_get_schema");
pm. expect(ajv. validate(JSON. parse(schema), pm. response. json())). to. be. true;
});
14.3 CDCプロバイダ検証(擬似)
bash pact-broker can-i-deploy --pacticipant wallets --version $SHA --to-environment staging
15) Prod Readinessチェックリスト
- リポジトリ内の契約、CIはアーティファクトを検証および公開します。
- 重要な統合のためにCDCを有効にしました。broker/matrix 「can-i-deploy」が動作します。
- 互換性ポリシー(HTTP/gRPC/Events)文書化;自動セマンティックdiff。
- 負の契約:エラー、サイズ制限、idempotence、 'Retry-After'。
- テストデータは決定論的です;例のスナップショットがサポートされています。
- バージョン管理と非推奨:締め切り、通知、ヘッダー。
- イベントの場合-スキーマレジストリと互換モード;生産者/消費者は両方のバージョンをテストしています。
- アーティファクト:JUnit/HTML、差分/検証レポート、互換性マトリックス。
- インシデントプロシージャ:高速契約ロールバック/機能フラグ、インテグレータへの通知。
16) TL;DRについて
顧客の期待に対するCDC、実装に合わせた仕様テスト、イベントのスキーマレジスタ。厳密な互換性ポリシーと負の契約(エラー、制限、idempotence)を維持します。変更を破ることなく、緑のcan-i-deploy行列とsemantic-diffなしでリリースすることはできません。