モック、スタブ、フェイク、エミュレーター: コーディング エージェントを使用した API 呼び出しのテスト

コードが API を呼び出すときは、実際の API が失敗するのを待たずにテストする方法が必要です。 5 種類のスタンドインから選ぶことができます。 これらの名称は厳密に区別せずに使われるため、この記事での使い分けを以下に示します。

  • スタブ: HTTP クライアントや SDK の呼び出しを処理中に置き換え、あらかじめ用意された応答を返す機能。 この方法は高速で再現性が高く、記述した応答に対するロジックを検証できます。
  • モック: テストで呼び出しを確認できるように、コードが呼び出した方法も記録するスタブです。 スタブまで到達します。
  • 偽のサーバー: アプリが実際の API の代わりに HTTP 経由で呼び出す小規模な簡易サーバー (多くの場合、メモリ内)。 HTTP クライアントの動作を確認できますが、アプリでその URL を指定する必要があります。
  • エミュレーター: 通常、サービスの所有者によって公開される、サポートする操作に関しては実際のサービスと同様に動作するサービスのローカル バージョン。 エラー処理にこれを利用する前に、どのような制限やエラーに対応しているかを確認してください。
  • インターセプティングプロキシ: アプリと API の間のネットワーク上に配置されます。 アプリは実際の URL にアクセスし、プロキシは要求を渡すか、定義した応答でそれらの一部に応答します。 アプリは通信をプロキシ経由で送信し、HTTPS の場合はプロキシの証明書を信頼する必要があります。

API を呼び出すコードをテストする方法

Approach テスト対象 必要なもの 適切なタイミング
スタブまたはモック あなたの特定の応答に対するロジック ご利用のテスト フレームワーク 単体テストでビジネス ロジック、解析、エラー 分岐をテストする
偽のサーバー HTTP クライアントとシリアル化 アプリ内のベースURL設定または設定スイッチ API がまだ存在しないか、または UI 作業用に安定したバックエンドが必要です
Emulator サポートされている操作の実際のサービスに近い動作 別のエンドポイントまたは接続文字列 サービスの所有者が 1 つ配布し、あなたはオフライン開発を行う
テストアカウント付きの実際の API 実際に運用で使用するもの 資格情報、クォータ、料金 メインパスを最初から最後まで検証する
インターセプティング プロキシ 実際の URL でのアプリの実行状況 (SDK の再試行や応答ヘッダーを含む) プロキシ設定と証明書の信頼設定 アプリを変更せずに、エラー、制限、待機時間をテストできます

これらの 1 つ以上が必要です。 スタブは単体テストを高速に保ちます。 プロキシは、実際の API が不適切な動作をした場合のアプリ全体の動作を示します。 2 の組み合わせの詳細については、「Dev Proxy と単体テスト」を参照してください。

コーディング エージェントが構築するもの

コーディング エージェントに、アプリが API のエラーに対処できるようにし、それが機能することを確認するよう依頼すると、エージェントが代わりに適切な例を選んでくれます。 どれなのかを知るために、3 つのコーディング エージェント (210 回の実行) でテストを実行しました。 タスクでは、"レート制限を適切に処理して動作することを示す"、"実際の API 呼び出しにコストをかけずに検証する"、"OpenAI キーやインターネット接続なしでこれを実行する" などの言い回しが使用されました。

  • 動作するコードが求められた 140 回の実行のうち、76% において、エージェントは fetch スタブ httpx.MockTransport や使い捨ての HTTP サーバーを使用して、手動で失敗を再現しました。
  • GitHub、OpenAI、または天気 API を呼び出すアプリの 105 回の実行のうち 61 回において、エージェントはアプリにベース URL または設定スイッチを追加し、偽の API にアクセスできるようにしました。
  • 実際のAPIが使用可能で、プロンプトで除外されなかった75回の実行では、そのうち、実際のAPI URLでアプリをテストした実行は0件でした。

スタブは、単体テストに適した選択肢です。 そのギャップとは、彼らが省いている部分です。エージェントのスタブは、エージェントが想定しているエラーを返しますが、それが API から送られるエラーと一致するとは限りません。 そして、アプリを使用して偽の配布にアクセスできるようにするために追加されたスイッチです。

エージェントのテストを扱う方法

  • ロジック用のスタブを保持します。 それらは高速で、エージェントが作成したブランチをテストします。
  • 実際のエラー形式を確認します。 プロバイダーの文書化された状態コード、ヘッダー、および本文フィールドに基づいて、各シミュレーションエラーを作成するようエージェントに依頼します。 ベア 429 では、アプリが retry-after を読み取ったり、課金エラーとレート制限を区別したりすることはテストされません。
  • テスト用に追加されたスイッチの確認 エージェントが、テストがフェイクにアクセスできるようにするためだけにベース URL の設定を追加する場合、その設定を運用するコードに含めるかどうかを判断してください。
  • 実際の URL で、障害をシミュレートした状態でアプリを 1 回実行します。 リリースする前に、実行中のアプリ、SDK、再試行ポリシーが API 独自のエラーで何を行うかを確認します。 エージェントのエラー処理を段階的に確認するには、「コーディング エージェントが記述したエラー処理を確認する方法」を参照してください。

アプリで試す

Dev Proxy は、開発用のインターセプト プロキシです。 アプリが既に呼び出している URL に対して定義した応答が返され、アプリのコードは変更されません。 設定ファイルで MockResponsePlugin を有効にしてください: devproxyrc.json

{
  "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/rc.schema.json",
  "plugins": [
    {
      "name": "MockResponsePlugin",
      "enabled": true,
      "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
      "configSection": "mocksPlugin"
    }
  ],
  "urlsToWatch": [
    "https://api.contoso.com/*"
  ],
  "mocksPlugin": {
    "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/mockresponseplugin.schema.json",
    "mocksFile": "mocks.json"
  }
}

次に、 mocks.jsonで応答を定義します。 これは、予測エンドポイントに対して Retry-After ヘッダーとともに 503 を返します:

{
  "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/mockresponseplugin.mocksfile.schema.json",
  "mocks": [
    {
      "request": {
        "url": "https://api.contoso.com/v1/forecast*",
        "method": "GET"
      },
      "response": {
        "statusCode": 503,
        "headers": [
          {
            "name": "Retry-After",
            "value": "10"
          }
        ],
        "body": {
          "error": "Service unavailable"
        }
      }
    }
  ]
}

開発プロキシを起動し、通常どおりにアプリを実行してください:

devproxy --config-file devproxyrc.json

モックと一致しない要求は、実際の API に送信されます。 まだ存在しないバックエンドが必要な場合、CrudApiPlugin はメモリ内データを使用して CRUD API をシミュレート します。 毎回ではなくランダムにリクエストの一部を失敗させる場合は、「ランダムなエラーでアプリをテスト」を参照してください。 開発プロキシをインストールするには、「 開発プロキシの設定」を参照してください。

次のステップ

参照