Тестирование http-сервисов по спецификации OpenAPI

25 апреля 2023

Тестирование http-сервисов по спецификации OpenAPI

Разработка программного продукта - это длительный процесс, включающий в себя этапы анализа требований, проектирования, непосредственной реализации, тестирования, релиза и поддержки. В идеальном варианте - все этапы должны вытекать один из другого. Когда мы говорим об API - то это значит что спроектированные эндпоинты должны быть реализованы именно в том виде, в каком были спроектированы, а тесты должны проверять как корректность реализации, так и соответствие проекту. Это очень важно, т.к. спроектированные интерфейсы могут одновременно реализовываться разными командами на разных языках. В качестве стандарта проектирования API мы используем спецификацию OpenAPI 3.0, которая позволяет описать REST API и просмотреть его в удобном формате. Кроме этого при помощи сторонних инструментов мы можем поднять mock-сервис для удобства разработки. Но сейчас я хочу рассказать о том как спецификация OpenAPI помогает нам автоматически дополнять тесты и проверять их на соответствие спецификации.

Основным инструментом для работы с тестами API для нас является portman - это комбайн, позволяющий:

  • сконвертировать спецификацию OpenAPI в коллекцию Postman
  • расширить полученную коллекцию при помощи:

    • заполнения переменных коллекции
    • добавления контрактных, вариационных и интеграционных тестов
    • добавления своих скриптов в коллекцию
    • изменения запросов Postman

  • заполнить параметры выполнения запросов случайными, фиксированными или полученными по определённым правилам данными
  • запустить тестирование коллекции через Newman
  • выгрузить коллекцию в вашу учётную запись Postman
  • подключить всё вышеописанное в ваш контур CI/CD

В portman встроено добавление следующих видов контрактных тестов:

  • statusSuccess - проверяет что ответ на запрос Postman вернул код 2xx
  • statusCode - проверяет что ответ на запрос Postman вернул указанный в параметрах теста код
  • responseTime - проверяет время выполнения теста
  • contentType - проверяет что соответствующий заголовок присутствует в реквизите content-type, указанному в спецификации OpenAPI
  • jsonBody - проверяет что тело ответа в формате JSON
  • schemaValidation - проверяет что тело ответа соответствует JSON-схеме, указанной в спецификации OpenAPI
  • headersPresent - проверяет что заголовки ответа соответствуют указанным в спецификации OpenAPI

Попробуем посмотреть на данный инструмент поближе. Portman написан на Node.js, поэтому для его работы нам потребуется установить его локально или воспользоваться docker-образом. Установка производится через npm:

npm install -g newman @apideck/portman

Дополнительно можно установить различные модули отчётов для newman, которые позволят выгрузку результатов теста в стороннюю информационную систему или позволят просмотреть результаты тестов в более удобном формате. Например мы используем модули newman-reporter-htmlextra (подробный отчёт выполнения тестов в формате HTML), newman-reporter-openapi (позволяет проанализировать “покрытие” эндпоинтов тестами в разрезе кодов ответа) и newman-reporter-junitfull (его мы используем чтобы увидеть количество ошибок в интерфейсе GitLab). Установим первые два:

npm install -g newman-reporter-htmlextra newman-reporter-openapi

В качестве примера спецификации OpenAPI возьмём стандартный petstore: https://petstore3.swagger.io/. Файл спецификации в формате json доступен по ссылке: https://petstore3.swagger.io/api/v3/openapi.json. Скачаем его, т.к. в процессе работы мы будем его изменять. Тем не менее, сам portman умеет работать как с файлами, так и со ссылками на спецификации.

Для первоначальной настройки portman предоставляем удобный интерфейс, который вызывается командой portman –init:

article-image

После выполнения всех шагов, portman создаст нужные конфигурационные файлы и даже подскажет как запустить тесты. Если мы попробуем сразу же запустить предложенную команду, то увидим следующую картину:

article-image

Это произошло потому что в спецификации не указан базовый адрес, относительно которого будут выполнятся все запросы. Не будем менять спецификацию, а просто укажем его при запуска portman:

portman --cliOptionsFile portman/portman-cli.json -b
https://petstore3.swagger.io/api/v3

Ситуация поменялась. Запросы уходят на нужные адреса. Некоторые из них выполняются успешно, некоторые выдают коды ошибок 500 или 404:

article-image

Тем не менее, тесты рапортуют о том что прошли успешно. Как мы видим, количество выполненных тестов равно нулю. Это произошло потому что мы не указали какие тесты нужно подключать в коллекцию Postman.

Создадим файл с настройками portman/portman-config.json:


{
    "version": 1.0,
    "tests": {
      "contractTests": [
        {
          "openApiOperation": "*::*",
          "statusSuccess": {
            "enabled": true
          },
          "responseTime": {
            "enabled": true,
            "maxMs": 300
          },
          "contentType": {
            "enabled": true
          },
          "jsonBody": {
            "enabled": true
          },
          "schemaValidation": {
            "enabled": true
          },
          "headersPresent": {
            "enabled": true
          }
        }
      ]
    }
  }

В настройках мы указали что для любого (*::*) запроса мы включили указанные тесты. Некоторые тесты (например время ответа) содержат дополнительные настройки. В нашем случае ответ должен быть получен за 300 мс.

Запустим portman на выполнение. Тесты упадут после первой же ошибки. Если нам важно чтобы тесты проходили полностью, это также можно сделать через конфигурационные файлы. В файле portman-cli.json добавим параметр:

"newmanOptionsFile": "portman/newman-config.json"

Далее создадим файл portman/newman-config.json с содержимым:


{
  "reporters": [ "cli", "htmlextra" ],
  "reporter": {
    "htmlextra": {
        "export": "./newman_report.html",
        "skipHeaders": ["Authorization"]
    }
  },
  "verbose": true,
  "abortOnFailure": false
}

Параметр abortOnFailure отвечает за прерывание тестов при первой же ошибке. Остальные параметры подключают дополнительные отчёты и настраивают их.

Запустим portman еще раз. Обратите внимание что выполнение запросов отображается более детально, тесты не прерываются при ошибках, а по итогам выполнения мы получим отчёт в формате html:

article-image

Кроме файлов отчётов, в каталоге с настройками также создаётся файл коллекции Postman. Откроем его и посмотрим на содержимое:

article-image

В коллекции мы можем увидеть все эндпоинты, указанные в спецификации, сгенерированные через portman тесты, параметры запросов и многое другое. Мы можем выполнить любой запрос, при этом он будет проверен созданными тестами.

Мы затронули лишь небольшую часть возможностей тестирования API через Portman. Возможно данный инструмент и выглядит сложно в первоначальной настройке, но он очень удобен в использовании.

Представим ситуацию - разработчик добавляет новый эндпоинт. В случае с классическими тестами он может забыть или не захотеть писать соответствующий тест. При использовании portman - тест будет добавлен автоматически. В самом простом случае нам даже не нужно его как-то настраивать. Но даже если эндпоинт требует каких-то определённых параметров, которые не заполнились автоматически, то тест просто упадёт и разработчику придется его дорабатывать. Таким образом мы контролируем что на каждый эндпоинт всегда присутствует как минимум один тест.

Подобрать решение для себя

Отправить заявку
Комментарии для сайта Cackle