コントラクトテスト:テスト戦略とフィクスチャ
認証やエラー形式を含むコンシューマの期待値は、マージ前にCIで実際のプロバイダに対して検証されます。HTTPステータスコードはコントラクトのいずれの側でもモックで置き換えることはできません。
パッケージの状態: 参照コンテキストは人間によるレビュー準備完了。コントラクトとテストシナリオは完成していますが、採用実装がこれらを通過したという保証はありません。
決定事項
サービスインターフェースはコンシューマ駆動のコントラクトによって管理されます:コンシューマは送信するリクエストと必要なレスポンス(認証ヘッダーやエラー本文を含む)を公開します。プロバイダのCIは、破壊的変更がマージされる前に実行中のプロバイダに対してこれらの期待値を検証します。ステータスコードを常に200にモックするテストはコントラクトテストではありません。
範囲
- HTTPまたはメッセージのコンシューマ・プロバイダペア、コントラクトの公開、CIでのプロバイダ検証、破壊的変更と追加的変更の分類。
- 認証・認可ヘッダーの存在、エラーオブジェクトの形式、成功時のペイロード。
- 独立して進化するバックエンドサービス。
このブロックの対象外
- 完全なエンドツーエンドのプロダクトジャーニーおよびUIスナップショットテスト。
- 非同期トピックのイベントスキーマ進化(独自の互換性ルールがあります)。
コントラクト
- 各コンシューマコントラクトはプロバイダ、操作、必須リクエストヘッダー、許容されるステータスコード(少なくとも1つのドキュメント化されたエラーステータスを含む)を指定します。
- プロバイダ検証は、必須フィールドの消失、ステータスコードの意味変更、エラーコードの名称変更があった場合にマージを失敗させます。
- 本番で使用される認証スキーム(例:ベアラーアクセストークン)は、コントラクト内で必須ヘッダーまたはクレームとして現れ、ハッピーパスのみで省略されることはありません。
- エラー応答は、コントラクトで合意された安定した機械的な
codeとHTTPステータスクラスを保持します。 - 追加的なオプションのレスポンスフィールドは互換性があります。消費されるフィールドの削除や型変更は破壊的変更です。
- コントラクトテストはプロバイダプロセスまたは実際のステータスコードを返す記録済みプロバイダフィクスチャに対して実行され、すべての失敗を200にマッピングするスタブは使用しません。
実装
- コンシューマテストからコントラクトをアーティファクトとして公開し、プロバイダパイプラインがハンドラ、シリアライザ、認証の変更時に取得します。
- 権限なしや未発見の操作もデフォルトのコンシューマスイートに含めます。
障害対応
- プロバイダが起動できない場合、パイプラインはコントラクトをスキップせずに失敗します。
- 破壊的変更はAPIバージョンを上げてコンシューマを移行させます。既存のコントラクトを弱めることはありません。
検証
- ブランチで消費されるフィールドを削除し、プロバイダCIが失敗することを確認します。
- 権限なしリクエストを再生し、契約された401または403の本文を期待します。
このパッケージ内の実行可能に見える例はフィクスチャおよび受け入れコントラクトです。
コレクションのルートから python tools/validate.py を実行してパッケージ構造とメタデータをチェックし、対象リポジトリでシナリオを実装・実行してください。
採用にあたっての前提
example.yamlの名前や数値は採用プロファイルであり、普遍的なデフォルトではありません。- 採用チームはアクター、データクラス、エラー語彙、所有権を自システムにマッピングする必要があります。
参考文献
- コンシューマ駆動コントラクトは Fowler によって https://martinfowler.com/articles/consumerDrivenContracts.html で説明されています。
- HTTPインターフェースの記述は OpenAPI 3.1 に従う場合がありますが、このブロックは特定のブローカーベンダーを要求しません。