夕方のオフィスで、テストはすべて通っているのに、つないだ画面がエラーになっているモニターを前に、首をかしげている開発者

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(提供する側)を呼んでいるとします。画面側のコードが読んでいるのは、次の3つです。

{
  "status": "shipped",
  "total": 1200,
  "shipped_at": "2026-10-20T09:30:00+09:00"
}

画面側の単体テストは、この形のモックで全部通っています。でも、AIに観点を洗わせて、実際のレスポンスと突き合わせてみると、こんなズレが見つかることがあります。

観点画面側の思い込み実際のAPI起きること
型total は数値金額の精度を保つため文字列 "1200" で返す合計の計算や表示の整形でエラー、または文字列の連結になる
nullshipped_at は必ず入っている発送前は null日付の変換で例外が出て、画面ごと表示されない
取りうる値status は paid か shipped先月から cancelled が増えた想定外の値で分岐に入らず、表示が空になる
エラー時の形エラーでも同じ形で返る404のときは {"error": "..."} だけstatus が無くて、別の所で落ちる

どれも、提供する側から見れば「仕様どおり」の振る舞いです。悪いのはどちらでもなく、約束が書かれていなかったことです。

放っておくと、何が起きるか

逆に、契約が一度書かれていれば、提供する側は変更する前に「この変更で、どの使う側が困るか」を自分のテストで知ることができます。ここが、契約テストのいちばんありがたいところです。

契約テストの観点をAIに洗わせる4ステップ

左に画面を作る側の開発者、右にAPIを作る側の開発者がいて、真ん中の1枚の約束の書類を両側から指差して確かめ合っている図
使う側と提供する側が、同じ1枚の約束を両側から確かめる——それが契約テスト

ステップ1:連携をひとつ選び、使う側が「実際に読んでいる項目」を洗わせる

最初から全部のAPIに契約を書こうとしなくて大丈夫です。最近ズレで困った連携、または変更が多い連携をひとつ選びます。

AIには、APIの仕様書ではなく、使う側のコードを渡して「このコードがレスポンスのどの項目を、どう使っているか」を洗い出してもらいます。

ここで大事なのは、契約に書くのは「使う側が実際に読んでいる項目」だけということです。レスポンスの全項目を契約にすると、提供する側は使われていない項目すら変えられなくなり、契約がかえって足かせになります。

社外のAIサービスにコードを渡すときは、会社のルールで渡してよいものかを先に確認しておきましょう(目安は社内データをAIに渡す前の線引きにまとめています)。

ステップ2:観点を指定して、ズレそうな所を挙げさせる

「契約テストを書いて」とだけ頼むと、AIはそれらしいテストコードを一気に書いてくれます。でも、その前に観点の洗い出しだけを頼むほうが、抜けに気づきやすくなります。たとえばこんな頼み方です。

次のコードは、外部の注文APIのレスポンスを使っている画面側の処理です。
契約テストを書く前に、相手チームと確認すべき観点を整理したいです。

## お願いしたいこと
- このコードが読んでいるレスポンスの項目を、すべて挙げてください
- 項目ごとに、次の観点で「このコードが暗黙に前提にしていること」を書いてください
  - 型(数値か文字列か、など)
  - 必須か、無いことがあるか
  - null になりうるか
  - 取りうる値(列挙値。想定外の値が来たらどうなるか)
  - 日付・金額などの形式
  - 空の配列や0件のときの扱い
- エラー時(4xx / 5xx)のレスポンスの形を、このコードがどう前提にしているか
- 前提が崩れたとき、このコードがどう振る舞うか(例外になる/黙って表示が変わる)
- コードから確実に言えることと、推測を分けてください

## してほしくないこと
- テストコードや修正案は、まだ書かないでください
- コードに出てこない項目を、想像で付け足さないでください

(ここにコード)

最後の「想像で付け足さない」は効きます。AIはよくある注文APIの形を知っているので、放っておくとありそうな項目を足してしまうことがあるからです(いわゆるハルシネーションです)。

ステップ3:仕様書・実際のレスポンス・相手チームと突き合わせる

ここが、いちばん大事なステップです。AIが出してくれたのは、あくまでこちら側の前提の一覧。それが合っているかは、次の3つと突き合わせて確かめます。

  1. 仕様書:OpenAPI(APIの形を機械が読める形式で書いた仕様書)などがあれば、型・必須・列挙値を照らし合わせる
  2. 実際のレスポンス:検証環境で実際に呼んで、ふだんのケースに加えて発送前・キャンセル済み・存在しないIDなど、前提が崩れそうなケースを1〜2個見る
  3. 相手チーム:仕様書に書かれていないこと、仕様書と実際が違うことは、自分で決めずに相手に聞く

3つ目は、少し気が重いかもしれません。でも、聞き方を「御社のAPIがおかしい」ではなく、「こちらはこう前提にしているのですが、合っていますか?」にすれば、ぐっと話しやすくなります。AIの洗い出し結果を表にして見せれば、話も具体的に進みます。

ここで合意できたことが、そのまま「契約」になります。

ステップ4:合意できた分だけ、まず1本の契約テストにする

合意できたら、ようやくテストにします。やり方はいくつかあり、チームの状況で選べば大丈夫です。

やり方向いている状況
使う側起点の契約テストツール(代表的なものにPact。JVMならSpring Cloud Contractなど)使う側と提供する側が、どちらも社内のチームで、両方のCIに手を入れられる
仕様書(OpenAPIなど)に対するスキーマ検証仕様書がきちんと保守されている。または提供する側が社外で、相手のテストには手を入れられない
使う側のテストで、実レスポンスの形だけを定期的に確かめるまずは小さく始めたい。相手の変更に早く気づければ十分

どのやり方でも、AIにはテストコードの下書きを書いてもらえます。そのときは、ステップ3で合意した表をそのまま前提として渡すのがコツです。合意していない項目をAIが勝手に契約に入れていないかは、出てきたテストを見て必ず確かめます。

そして、最初の1本は、いちばんズレが怖い項目ひとつで十分です。先ほどの例なら「shipped_at は発送前に null になる」だけ。1本がCIで回り始めれば、そこに観点を足していくのは難しくありません。

テスト全体のどこを厚くするかで迷ったら、AIにテスト戦略を相談する|どこを厚く薄くするかの決め方も参考にどうぞ。

明日やること(小さく始める3つ)

  1. 最近ズレで困った連携をひとつ思い出す:「あのとき、何がズレていたか」を一行メモするだけでも、最初の観点になります。
  2. その連携の使う側のコードを、上のテンプレでAIに渡す:返ってきた一覧のうち、「推測」と付いた所がひとつ見つかれば十分な収穫です。
  3. 気になった項目をひとつだけ、相手チームに確認する:「こちらはこう前提にしていますが、合っていますか?」の一言で大丈夫です。

契約テストの観点 チェックリスト

【必須】の3つだけでも、「つないだら壊れた」をかなり減らせます。 残りは余裕があるときに。

最後に

API連携のズレは、誰かの手抜きから生まれるものではありません。それぞれが自分の持ち場をきちんと作った結果、間に小さな隙間ができていただけです。 契約テストは、その隙間に「ここは同じものを見ていますよね」と、1枚の約束を置く作業です。AIは、その約束の下書きを作るのが得意です。でも、約束を交わすのは、人と人です。

明るいオフィスで、別々のチームの開発者2人がノートパソコンの画面を一緒に見ながら、笑顔でうなずき合っている
約束を一度書けば、相手の変更はもう怖くない

最初の1本が回り始めると、相手の変更を「怖いもの」ではなく「先に教えてもらえるもの」として受け取れるようになります。 まずは明日、最近ズレで困った連携をひとつ選んで、使う側のコードをAIに読ませてみるところから始めてみましょう。

よければ、こちらも

関連用語