Моки, заглушки, фейки и эмуляторы: тестирование вызовов API с помощью агентов кодирования

Когда код вызывает API, вам нужен способ его тестирования, не дожидаясь, пока реальный API даст сбой. У вас есть 5 типов заменителей для выбора. Люди вольно используют эти названия, поэтому вот как эта статья использует их:

  • Заглушка: замена вызова HTTP-клиента или пакета SDK в рамках процесса, возвращающая заранее подготовленный ответ. Это быстро и повторяемо, и проверяет логику в написанном вами ответе.
  • Mock: заглушка, которая также записывает, как ваш код вызывал её, чтобы тест мог проверить вызовы. Доходит до заглушки.
  • Фиктивный сервер: небольшой, но рабочий сервер, часто развёрнутый в памяти, к которому приложение обращается по HTTP вместо настоящего API. Он задействует ваш HTTP-клиент, но вам нужно направить приложение на его URL-адрес.
  • Эмулятор: локальная версия сервиса, обычно предоставляемая владельцем сервиса, которая работает как настоящий сервис при выполнении поддерживаемых ею операций. Проверьте, какие ограничения и виды отказов он покрывает, прежде чем полагаться на него при обработке ошибок.
  • Перехватывающий прокси-сервер: находится в сети между приложением и API. Ваше приложение обращается к реальному URL-адресу, а прокси-сервер либо перенаправляет запросы дальше, либо сам отвечает на некоторые из них заранее заданным ответом. Ваше приложение должно отправлять свой трафик через прокси-сервер, а для HTTPS нужно доверять сертификату прокси-сервера.

Тестирование кода, вызывающего API

Approach Что он проверяет Что требуется Как только
Заглушка или мок Ваша логика для определенного ответа Ваш тестовый фреймворк Вы тестируете бизнес-логику, синтаксический анализ и ветви ошибок в модульных тестах
Фиктивный сервер Http-клиент и сериализация Параметр базового URL-адреса или переключатель конфигурации в приложении API еще не существует, или вам нужна стабильная серверная часть для работы пользовательского интерфейса.
Эмулятор Поведение, близкое к реальному сервису, для поддерживаемых операций Другая конечная точка доступа или строка подключения Владелец службы поставляет его, а вы разрабатываете в офлайн-режиме
Реальный API с тестовой учетной записью Настоящая вещь Учетные данные, квота и деньги Проверьте основной сценарий от начала до конца
Перехватывающий прокси-сервер Ваше запущенное приложение на реальных URL-адресах, включая повторные попытки SDK и заголовки ответов Параметры прокси-сервера и доверие к сертификату Вы тестируете сбои, ограничения и задержки без изменения приложения

Вам потребуется более 1 из них. Заглушки помогают модульным тестам выполняться быстро. Прокси-сервер показывает, что делает все приложение, когда реальный API работает некорректно. Дополнительные сведения о том, как эти два подхода сочетаются, см. в статье Dev Proxy и модульные тесты: сравнение.

Что создают агенты программирования

Когда вы просите агента по программированию сделать так, чтобы приложение обрабатывало сбои API и показывало, что оно работает, он выбирает для вас заглушку. Мы хотели знать, какой из них, поэтому мы выполнили тест с 3 агентами кодирования (210 запусков). Задачи использовали фразы, такие как "правильно обрабатывать ограничение скорости и показать мне, что это работает", "проверить его, не тратя деньги на реальные вызовы API", и "запустить это без ключа OpenAI или подключения к Интернету".

  • В 76% из 140 запусков, запрашивающих рабочий код, агент вручную воссоздал сценарий сбоя: заглушки fetch, httpx.MockTransport, или временный HTTP-сервер.
  • В 61 из 105 запусков приложений, которые обращаются к GitHub, OpenAI или API погоды, агент добавил в приложение базовый URL-адрес или переключатель конфигурации, чтобы приложение могло обращаться к своей имитации.
  • В 75 запусках, где был доступен реальный API и запрос не исключал его, ни в одном приложение не было протестировано по его реальному URL-адресу API.

Заглушки являются разумным выбором для модульных тестов. Пробел в том, что они опускают. Заглушка агента возвращает ошибку, которую ожидал агент, и она может не соответствовать тому, что отправляет API. И переключатель, который он добавил для подключения к ложным узлам через ваше приложение.

Как работать с тестами агента

  • Сохраните стабы для вашей логики. Они работают быстро и проверяют ветки, которые создал агент.
  • Запросите реальный формат ошибки. Попросите агента основывать каждую имитированную ошибку на документированных кодах состояния, заголовках и полях тела поставщика. Один лишь код 429 не проверяет, что приложение обрабатывает retry-after или отличает ошибку биллинга от ограничения скорости.
  • Проверьте переключатели, добавленные для тестов. Если агент добавляет базовый параметр URL-адреса только для того, чтобы тесты могли обращаться к заглушке, решите, хотите ли вы установить этот параметр в рабочем коде.
  • Запустите приложение один раз на реальных URL-адресах с имитацией сбоев. Перед отправкой проверьте, что выполняется приложение, его пакет 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. Этот запрос возвращает 503 с заголовком Retry-After для конечной точки прогноза:

{
  "$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 имитирует API CRUD с данными в памяти. Чтобы случайным образом завершать часть запросов с ошибкой, а не каждый раз, см. статью Тестирование приложения со случайными ошибками. Чтобы установить Dev Proxy, см. статью Настройка Dev Proxy.

Дальнейшие действия

См. также