
AIに契約テストの観点を洗わせる|API連携の齟齬を本番前に防ぐ
「単体テストは全部グリーン。モックで返り値も確かめた。なのに、検証環境でつないだら画面が真っ白」 ログを見ると、相手のAPIが返していた total が、こちらの想定していた数値ではなく文字列だった——。
API連携で起きるこの手のトラブルは、どちらかが雑な仕事をしたから起きるわけではありません。こちらは「こう返ってくるはず」で、相手は「こう返している」で、それぞれ正しく作っている。ただ、その2つを突き合わせる場所が、どこにもなかっただけです。
その「突き合わせる場所」を作るのが、契約テスト(Contract Test)です。そして、契約に何を書くべきか——つまり観点の洗い出しは、AIがかなり手伝ってくれる仕事です。 この記事では、AIに契約テストの観点を洗わせて、相手と突き合わせ、小さな1本から始めるまでの進め方を一緒に整理します。
結論:契約テストは「使う側と提供する側が、APIの形について同じ約束を見ているか」を確かめるテストです。AIに任せるなら、手順は4つ。①連携をひとつ選び、使う側が実際に読んでいる項目をAIに洗い出させる/②型・必須かどうか・null・取りうる値・エラー時の形などの観点で、ズレそうな所を挙げさせる/③その結果を、仕様書と実際のレスポンス、そして相手チームと突き合わせる/④合意できた分だけ、まず1本の契約テストにしてCIで回す。いちばん大事なのは③。AIの洗い出しは「たたき台」で、契約を決めるのは人どうしの合意です。
何が起きているのか——モックは「自分の思い込み」を返す
API連携の単体テストでは、相手のAPIをモック(本物の代わりに決まった値を返す偽物)に置き換えるのが普通です。速くて、安定していて、便利です。
ただ、モックが返す値はこちらが書いた値です。つまり、モックを使ったテストが確かめているのは「自分の思い込みどおりにデータが来たら、正しく動く」ことまで。相手が本当にその形で返しているかは、どこでも確かめていません。
AIにモックやテストを書かせると、この傾向は少し強まります。AIはこちらのコードから「たぶんこういう形で返ってくるだろう」という、いちばん自然な形を想像してモックを作るからです(このあたりはAIにモック・スタブを書かせる|テストが嘘をつかない確認でも触れました)。
一方で、結合テストやE2Eテストで本物どうしをつなげば、ズレには気づけます。でも、環境の準備が大変で、遅く、落ちたときに原因の切り分けにも時間がかかります。
契約テストは、その間を埋めるものです。
- 使う側は、「自分はこの形のレスポンスを前提にしている」という約束(契約)を書く
- 提供する側は、「自分のAPIは、その約束どおりに返している」かを自分のテストで確かめる
本物どうしをつながなくても、同じ約束を両側から確かめることで、ズレを早めに見つけられます。
具体例:注文APIの「ちょっとしたズレ」
たとえば、画面側(使う側)が、別チームの注文API(提供する側)を呼んでいるとします。画面側のコードが読んでいるのは、次の3つです。
{
"status": "shipped",
"total": 1200,
"shipped_at": "2026-10-20T09:30:00+09:00"
}
画面側の単体テストは、この形のモックで全部通っています。でも、AIに観点を洗わせて、実際のレスポンスと突き合わせてみると、こんなズレが見つかることがあります。
| 観点 | 画面側の思い込み | 実際のAPI | 起きること |
|---|---|---|---|
| 型 | total は数値 | 金額の精度を保つため文字列 "1200" で返す | 合計の計算や表示の整形でエラー、または文字列の連結になる |
| null | shipped_at は必ず入っている | 発送前は null | 日付の変換で例外が出て、画面ごと表示されない |
| 取りうる値 | status は paid か shipped | 先月から cancelled が増えた | 想定外の値で分岐に入らず、表示が空になる |
| エラー時の形 | エラーでも同じ形で返る | 404のときは {"error": "..."} だけ | status が無くて、別の所で落ちる |
どれも、提供する側から見れば「仕様どおり」の振る舞いです。悪いのはどちらでもなく、約束が書かれていなかったことです。
放っておくと、何が起きるか
- ズレに気づくのが、いちばん遅い段階になる:検証環境、悪ければ本番で初めて分かります。そこから原因を探すと、どちらのチームの変更が原因か、切り分けだけで半日かかることもあります。
- 相手の変更が、こちらから見えない:提供する側は、
cancelledを足すのが「画面を壊す変更」だとは知りようがありません。知らせる仕組みが無いからです。 - チームの間に、小さな不信が溜まる:「また向こうが勝手に変えた」となりやすいのですが、実際は約束を書く場所が無かっただけ、ということがほとんどです。
逆に、契約が一度書かれていれば、提供する側は変更する前に「この変更で、どの使う側が困るか」を自分のテストで知ることができます。ここが、契約テストのいちばんありがたいところです。
契約テストの観点をAIに洗わせる4ステップ

ステップ1:連携をひとつ選び、使う側が「実際に読んでいる項目」を洗わせる
最初から全部のAPIに契約を書こうとしなくて大丈夫です。最近ズレで困った連携、または変更が多い連携をひとつ選びます。
AIには、APIの仕様書ではなく、使う側のコードを渡して「このコードがレスポンスのどの項目を、どう使っているか」を洗い出してもらいます。
ここで大事なのは、契約に書くのは「使う側が実際に読んでいる項目」だけということです。レスポンスの全項目を契約にすると、提供する側は使われていない項目すら変えられなくなり、契約がかえって足かせになります。
社外のAIサービスにコードを渡すときは、会社のルールで渡してよいものかを先に確認しておきましょう(目安は社内データをAIに渡す前の線引きにまとめています)。
ステップ2:観点を指定して、ズレそうな所を挙げさせる
「契約テストを書いて」とだけ頼むと、AIはそれらしいテストコードを一気に書いてくれます。でも、その前に観点の洗い出しだけを頼むほうが、抜けに気づきやすくなります。たとえばこんな頼み方です。
次のコードは、外部の注文APIのレスポンスを使っている画面側の処理です。
契約テストを書く前に、相手チームと確認すべき観点を整理したいです。
## お願いしたいこと
- このコードが読んでいるレスポンスの項目を、すべて挙げてください
- 項目ごとに、次の観点で「このコードが暗黙に前提にしていること」を書いてください
- 型(数値か文字列か、など)
- 必須か、無いことがあるか
- null になりうるか
- 取りうる値(列挙値。想定外の値が来たらどうなるか)
- 日付・金額などの形式
- 空の配列や0件のときの扱い
- エラー時(4xx / 5xx)のレスポンスの形を、このコードがどう前提にしているか
- 前提が崩れたとき、このコードがどう振る舞うか(例外になる/黙って表示が変わる)
- コードから確実に言えることと、推測を分けてください
## してほしくないこと
- テストコードや修正案は、まだ書かないでください
- コードに出てこない項目を、想像で付け足さないでください
(ここにコード)
最後の「想像で付け足さない」は効きます。AIはよくある注文APIの形を知っているので、放っておくとありそうな項目を足してしまうことがあるからです(いわゆるハルシネーションです)。
ステップ3:仕様書・実際のレスポンス・相手チームと突き合わせる
ここが、いちばん大事なステップです。AIが出してくれたのは、あくまでこちら側の前提の一覧。それが合っているかは、次の3つと突き合わせて確かめます。
- 仕様書:OpenAPI(APIの形を機械が読める形式で書いた仕様書)などがあれば、型・必須・列挙値を照らし合わせる
- 実際のレスポンス:検証環境で実際に呼んで、ふだんのケースに加えて発送前・キャンセル済み・存在しないIDなど、前提が崩れそうなケースを1〜2個見る
- 相手チーム:仕様書に書かれていないこと、仕様書と実際が違うことは、自分で決めずに相手に聞く
3つ目は、少し気が重いかもしれません。でも、聞き方を「御社のAPIがおかしい」ではなく、「こちらはこう前提にしているのですが、合っていますか?」にすれば、ぐっと話しやすくなります。AIの洗い出し結果を表にして見せれば、話も具体的に進みます。
ここで合意できたことが、そのまま「契約」になります。
ステップ4:合意できた分だけ、まず1本の契約テストにする
合意できたら、ようやくテストにします。やり方はいくつかあり、チームの状況で選べば大丈夫です。
| やり方 | 向いている状況 |
|---|---|
| 使う側起点の契約テストツール(代表的なものにPact。JVMならSpring Cloud Contractなど) | 使う側と提供する側が、どちらも社内のチームで、両方のCIに手を入れられる |
| 仕様書(OpenAPIなど)に対するスキーマ検証 | 仕様書がきちんと保守されている。または提供する側が社外で、相手のテストには手を入れられない |
| 使う側のテストで、実レスポンスの形だけを定期的に確かめる | まずは小さく始めたい。相手の変更に早く気づければ十分 |
どのやり方でも、AIにはテストコードの下書きを書いてもらえます。そのときは、ステップ3で合意した表をそのまま前提として渡すのがコツです。合意していない項目をAIが勝手に契約に入れていないかは、出てきたテストを見て必ず確かめます。
そして、最初の1本は、いちばんズレが怖い項目ひとつで十分です。先ほどの例なら「shipped_at は発送前に null になる」だけ。1本がCIで回り始めれば、そこに観点を足していくのは難しくありません。
テスト全体のどこを厚くするかで迷ったら、AIにテスト戦略を相談する|どこを厚く薄くするかの決め方も参考にどうぞ。
明日やること(小さく始める3つ)
- 最近ズレで困った連携をひとつ思い出す:「あのとき、何がズレていたか」を一行メモするだけでも、最初の観点になります。
- その連携の使う側のコードを、上のテンプレでAIに渡す:返ってきた一覧のうち、「推測」と付いた所がひとつ見つかれば十分な収穫です。
- 気になった項目をひとつだけ、相手チームに確認する:「こちらはこう前提にしていますが、合っていますか?」の一言で大丈夫です。
契約テストの観点 チェックリスト
【必須】の3つだけでも、「つないだら壊れた」をかなり減らせます。 残りは余裕があるときに。
- 【必須】契約に入れる項目を、使う側が実際に読んでいる項目に絞ったか
- 【必須】AIの洗い出しを、仕様書か実際のレスポンスで確かめたか(AIの一覧をそのまま契約にしていないか)
- 【必須】仕様書に無いこと・食い違いを、自分で決めずに相手チームに確認したか
- (余裕があれば)型(数値か文字列か)を確認したか
- (余裕があれば)null になる項目、無いことがある項目を確認したか
- (余裕があれば)列挙値に想定外の値が来たときの振る舞いを決めたか
- (余裕があれば)日付・金額の形式を確認したか
- (余裕があれば)エラー時(4xx / 5xx)のレスポンスの形を確認したか
- (余裕があれば)AIが書いたテストに、合意していない項目が紛れ込んでいないか見たか
- (余裕があれば)契約テストを、使う側・提供する側の両方のCIで回せているか
最後に
API連携のズレは、誰かの手抜きから生まれるものではありません。それぞれが自分の持ち場をきちんと作った結果、間に小さな隙間ができていただけです。 契約テストは、その隙間に「ここは同じものを見ていますよね」と、1枚の約束を置く作業です。AIは、その約束の下書きを作るのが得意です。でも、約束を交わすのは、人と人です。

最初の1本が回り始めると、相手の変更を「怖いもの」ではなく「先に教えてもらえるもの」として受け取れるようになります。 まずは明日、最近ズレで困った連携をひとつ選んで、使う側のコードをAIに読ませてみるところから始めてみましょう。
よければ、こちらも
- AIにモック・スタブを書かせる|テストが嘘をつかない確認
- AIに外部API連携の設計を相談する|タイムアウトと障害の詰め方
- E2E・結合テストのシナリオをAIに書かせる——観点の渡し方
- AIにAPIエンドポイント設計を叩かせる|命名と粒度の詰め方
- 境界値・異常系をAIに考えさせて漏れを減らす手順