Postman в CI/CD: от локальных тестов к пайплайну

Перевод статьи «Postman: from local tests to our CD pipeline».

Разработчики API могут часами спорить о том, какой HTTP-метод, код состояния или название параметра использовать. А после выпуска релиза все рушится из-за непонятной сетевой проблемы в датацентре.

Каждый опытный тестировщик знаком с высокой эффективностью юнит-тестов или изолированных тестов, но, в конце концов, API – это история про перемещение данных внутрь ваших систем или из них, поэтому проводить полноценные end-to-end тесты всё равно необходимо. Рассмотрим, как Postman может нам в этом помочь.

Друзья, поддержите нас вступлением в наш телеграм канал QaRocks. Там много туториалов, задач по автоматизации и книг по QA.

Содержание

Тестирование с помощью Postman

Postman – это десктопный HTTP-клиент, который позволяет полностью контролировать форму запроса, отображает ответ с телом и заголовками, а также предоставляет множество различных метаданных.

Особенно полезной является вкладка “Тесты”, в которой можно создать JavaScript-тесты для проверки запроса и ответа на него. Программа предоставляет различные функции и переменные, можно даже использовать некоторые NPM-пакеты (например, AJV для проверки JSON-схемы в теле запроса).

Подробнее о тестах Postman можно узнать из официальной документации.

Пример теста, который проверяет код состояния и тело эндпоинта нашего токена

Коллекции

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

Одновременный запуск всех запросов из коллекции
Результат запуска коллекции

Все написанные для каждого запроса тесты будут выполнены и включены в общие результаты.

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

Автоматизация с Newman

Тестирование после деплоя может стать достаточно утомительным. Особенно если нужно быстро провести необходимые проверки, а приходится лишний раз лезть в Postman.

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

Для еще большего упрощения работы был придуман Newman – официальная командная строка Postman. Благодаря ей можно получить и экспортировать целую коллекцию.

Необходимо установить Newman CLI и запустить файл коллекции, а система уже отобразит краткую информацию о выполнении, включая статистику по количеству выполненных и проваленных тестов.

$ npm install -g newman
$ newman run sample-collection.json

Sample Postman Collection

→ A simple GET request
  GET https://postman-echo.com/get?source=newman-sample-github-collection [200 OK, 849B, 623ms]
  √  expect response be 200
  √  expect response json contain args

→ A simple POST request
  POST https://postman-echo.com/post [200 OK, 1.07kB, 290ms]

→ A simple POST request with JSON body
  POST https://postman-echo.com/post [200 OK, 1.18kB, 138ms]

┌─────────────────────────┬─────────────────────┬────────────────────┐
│                         │            executed │             failed │
├─────────────────────────┼─────────────────────┼────────────────────┤
│              iterations │                   1 │                  0 │
├─────────────────────────┼─────────────────────┼────────────────────┤
│                requests │                   3 │                  0 │
├─────────────────────────┼─────────────────────┼────────────────────┤
│            test-scripts │                   1 │                  0 │
├─────────────────────────┼─────────────────────┼────────────────────┤
│      prerequest-scripts │                   0 │                  0 │
├─────────────────────────┼─────────────────────┼────────────────────┤
│              assertions │                   2 │                  0 │
├─────────────────────────┴─────────────────────┴────────────────────┤
│ total run duration: 1387ms                                         │
├────────────────────────────────────────────────────────────────────┤
│ total data received: 2.13kB (approx)                               │
├────────────────────────────────────────────────────────────────────┤
│ average response time: 350ms [min: 138ms, max: 623ms, s.d.: 202ms] │
└────────────────────────────────────────────────────────────────────┘

Еще приятнее то, что можно запустить даже удаленную коллекцию, например, загруженную напрямую с Github. Не нужно клонировать или вытягивать. Она всегда актуальна.

$ newman run https://raw.githubusercontent.com/postmanlabs/newman/develop/examp
les/sample-collection.json

Обращение с учетными данными

В большинстве современных API используется аутентификация, следовательно для их тестирования необходимы учетные данные. Добавление набора идентификаторов и паролей непосредственно в запросы или в переменные нежелательно, так как это небезопасно.

К большому счастью, при запуске коллекции есть возможность использовать файл данных. Это простой JSON-файл, содержащий массив пар ключ-значение. Каждый ключ-значение — это переменная, которая и будет вводиться в коллекцию во время выполнения.

Например, в этом базовом файле данных объявлена одна переменная: token.

[
 { 
   "token":"mySuperSecretToken"
 }
]

При запуске коллекции переменная {{token}} становится доступной и ее можно использовать во всех запросах. Более подробно о переменных и областях видимости можно узнать на сайте Postman.

Запрос с использованием параметра {{token}}

А таким способом можно запустить коллекцию с помощью Newman, используя файл данных:

$ newman run sample-collection.json --iteration-data data.json

Все секретные данные для тестирования API были перегруппированы в один файл data.json, который каждый член команды хранит локально. Это означает, что никакая приватная информация не будет располагаться в коллекциях Postman, что делает их хранение в различных git-репозиториях безопасным.

Сценарии

Дальше – больше. Для удобства все вышеперечисленное обернули в bash-функцию. Она принимает ID репозитория в качестве аргумента, проверяет, что репозиторий действительно существует и содержит файл коллекции в нужном месте, и в результате запускает коллекцию с помощью Newman.

#Run the deployment Postman collection with Newman
#Parameter: the name of the repo (ex: "criteo-api/exam-oauth")
apiTest() {
 project=$1
 
 #Validate that the repo exists
 repoUrl="https://raw.githubusercontent.com/${project}"
 curl -silent -f -L $repoUrl -o /dev/null
 exit_status=$?
 if [ $exit_status != 0 ]
  then
   echo "Repo for project ${project} does not exist"
   return 1
 fi
 
 #Validate that the collection exist
 collectionUrl="${repoUrl}/deployment/postman_collection.json"
 curl -silent -f -L $collectionUrl -o /dev/null
 exit_status=$?
 if [ $exit_status != 0 ]
  then
   echo "Test collection for project ${project} does not exist"
   return 1
 fi

 #Validate that data.json exists
 dataFile=~/deployment-test/data.json
 if [ ! -f "$dataFile" ]; then
  echo "Local data file does not exist ($dataFile)."
  return 1
 fi
 
 #Run collection with newman
 newmanCommand="newman run ${collectionUrl} --iteration-data ${dataFile}"

 ${newmanCommand}
}

Теперь запуск коллекции Postman для репозитория можно выполнить с помощью этой простой команды:

$ apiTest my/repository

Интеграция с Concourse

В прошлом году мы начали переходить на полный конвейер CI/CD, когда каждое приложение автоматически развертывается еженедельно. При этом мы хотели использовать уже созданные нами тестовые коллекции Postman.

Наш CI/CD-конвейер – это Concourse. В Concourse все является контейнером, поэтому для того, чтобы добавить кастомный шаг, сначала необходимо настроить и создать специальный контейнер для него. Мы легко могли бы создать Docker-контейнер с установленным Newman, чтобы во время развертывания использовать его для запуска коллекции из нашего репозитория. Но в итоге столкнулись бы с той же проблемой с секретными данными, что и раньше: мы хотим избежать их хранения внутри самого контейнера.

После некоторого размышления мы решили создать собственное приложение, которое будет отвечать за получение коллекции из других хранилищ и данных из нашего экземпляра Vault (корпоративное хранилище секретов).

Приятно то, что это упрощает интеграцию с Vault и превращает весь запуск сценария в простой HTTP-запрос. Это означает, что его может легко выполнить и Concourse, и человек, и система планирования. Теперь мы вольны расширить его дополнительными возможностями в перспективе. Например, можем подтвердить, что API, тестируемый коллекцией, удовлетворяет спецификации OpenAPI этого самого API.

C4-схема предлагаемой архитектуры

Смешивание C# и Node.js?

Поскольку большинство наших внутренних приложений написано на C#, основное приложение также будет написано на этом языке. Но как запустить коллекцию Postman из приложения на C#?

Самый простой способ — установить Newman в тот же контейнер, что и C#-приложение, и выполнять системные вызовы. Но, опять же, плохая идея иметь две разнородные технологии в одном контейнере, особенно когда одна из них будет обращаться ко многим нашим API, а другая — иметь доступ к нашему секретному хранилищу.

В моем идеальном мире кто-то должен был создать “Newman-как-веб-сервис”, который выставлял бы простой stateless POST /run эндпоинт для запуска коллекции (с опциональным файлом данных). Никто этого не сделал, но это оказалось не очень сложным, поскольку Newman открыл свой собственный внутренний API для использования внутри приложения Node.js.

Newman-Server

Так на свет появился newman-server. Простой сервер, выполняющий коллекции Postman по требованию.

$ npm install -g newman-server
$ newman-server
Server started on port 8080

У него легкий фронтенд, но в основном он предназначен для использования только в качестве бэкенда.

Основа пользовательского интерфейса newman-server

Финальная интеграция

Когда все готово, мы можем добавить наш шаг валидации в Concourse.

Этот шаг выводит синтетическую версию JSON-отчета Newman, отбрасывая тела запросов и ответов (во избежание утечки секретных данных), но сохраняя статусы, чтобы можно было легко идентифицировать, в какой части теста появилась ошибка.

Здесь мы можем легко понять, что у нас проблема с аутентификацией.

Надеюсь, вам понравилось наше лаконичное описание варианта использования Postman для тестирования API. Смело внедряйте в ваш пайплайн и наслаждайтесь результатом!

1 комментарий к “Postman в CI/CD: от локальных тестов к пайплайну”

  1. Пингбэк: Большой учебник по Postman

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *