| August 18, 2022
Введение
Postman - это целая платформа для построения и использования различных API. Это бесплатный инструмент, выросший из простейшего REST клиента до гигантского размера клубка различных фич.
В нём есть как возможности использования различных API, так и возможности проектирования и создания новых, возможности запланированного опрашивания разных сервисов на предмет их жизнеспособности (так называемые health check’и), создания mock серверов и так далее.
В этой небольшой статье, я бы хотел затронуть одну из функций Postman, которая могла бы пригодится каждому разработчику - тестирование API’ев. А так же, поделюсь идеями о внедрении этой функции в Ваши будни разработчика.
Основная часть
Отправной точкой в тестирование Ваших сервис являются Коллекции Postman. Коллекции Postman - это раздел Postman, в котором Вы можете группировать и организовать управление Запросами. Запросы организуются в папки и под-папки, согласно Вашему замыслу.
Настройки Запросов в Коллекциях находятся в специальных разделах. Из них, для нас представляют интерес ровно два - Pre-request Script и Tests.
- Pre-request Script - содержит в себе код сценария, написанный на JavaScript, который будет выполнен ДО выполнения самого запроса. Это может быть полезно тогда, когда для запроса существуют некоторые пред-условия или же для данного конкретного запроса нужно сохранить какую-либо информацию, которую можно будет использовать на этапе тестирования результатов.
- Tests - содержит в себе код тестов, написанный на JavaScript. Код из этого раздела запускается после выполнения запроса и имеет доступ к ответу сервера.
Подопытный сервис
Достаточно теории. Переходим к практической части. Тесты пишутся для какого-то API. Поэтому для демонстрации создания тестов я буду использовать бесплатное публично API с сайта https://api.publicapis.org/entries.
Если просто перейти по ссылке выше, Вы сможете увидеть что именно вернёт наш GET запрос в Postman.
Создаём пред-условия
В разделе Pre-request Script мы можем описать сценарий, который будет выполнен до основного запроса. Какие это могут быть сценарии?
- Мы можем создать / запросить / организовать данные, необходимые для выполнения основного запроса
- Мы можем сохранить в переменные окружения наших тестов значения, которые могут понадобиться нам на этапе выполнения самих тестов. Хорошим примером данного подхода служит сохранение временной метки на момент вызова запроса, а затем, проверка временных меток в ответе сервера на предмет приближённости к тестовой.
На самом деле, возможности использования пред-условий не ограничены вышеназванными сценариями. Но, на мой взгляд, эти два - основные.
Для нашего примера, предлагаю рассмотреть следующий случай - В теле ответа, нам приходит набор объектов, общее число которых равно 1425 (на момент написания данного материала). Давайте претворимся, что мы ожидаем в ответе для данного запроса ровно 1425 объектов.
1425 - это магическое число и оно известно до выполнения запроса. Записать его в переменные окружения тестов можно следующим образом:
pm.environment.set('expected_count', 1425);
Пытливый читатель уже после этого кусочка кода может задать вопрос - а что такое этот pm
? pm
- это javascript объект, который доступен автору скриптов в Postman и именно с помощью этого объекта происходит работа с пред-условиями и тестами. Абсолютно всё, что мы можем делать в рамках наших тестов, делается через этот объект, поставляемый самим Postman.
Создаём тесты
Теперь дело за малым - написать наши тесты. Прежде чем мы начнём разработку скрипта с тестом, неплохо было бы понять, а что именно мы будем тестировать. Нам нужен план тестирования.
Предлагаю протестировать следующие момента:
- Статус ответа сервера должен быть равен 200
- Переменная
count
в теле ответа должна иметь значение 1425 (ожидаемый результат) - Количество элементов в массиве
entries
должно быть равно количеству, указанному вcount
- И, наконец, все элементы массива
entries
должны иметь ссылки, использующие протоколhttps
Статус ответа сервера должен быть равен 200
Тесты пишутся в разделе Tests
. Каждый новый тест описывается отдельной javascript функцией. Но чтобы сам Postman узнал о том, что конкретная функция является тестом, эту функцию мы должны передать Postman’у с помощью уже известной нам переменной pm
. Делается это следующим образом:
pm.test('Response code must be equal 200', () => {
pm.expect(pm.response.code).eql(200);
});
где
pm.test([Название теста], [Функция со сценарием теста])
- определение нового тестового сценарияpm.expect(pm.response.code).eql(200);
- тело самого тестового сценария
Как уже было сказано выше, pm
особенный объект, через интерфейс которого у нас есть доступ к запросам и ответам. Он так же позволяет писать assert’ы, с помощью функции expect
. В примере выше, мы утверждаем, что статус ответа сервера должен быть 200.
Переменная count
в теле ответа должна иметь значение 1425
Для реализации этого сценария, нам потребуется получить доступ к переменной окружения тестов, которую мы проинициализировали в разделе Pre-request Script
. Полный код тестового сценария будет выглядеть следующим образом:
pm.test('Response \'count\' field must be equal to expected value', () => {
var expectedCount = pm.environment.get('expected_count');
var json = pm.response.json();
pm.expect(json.count).eql(expectedCount);
});
где
pm.environment.get('expected_count')
- доступ к заранее определённой в предусловиях переменнойexpected_count
var expectedCount = ...
- объявление локальной переменной для удобства работы с даннымиpm.response.json()
- парсинг тела ответа сервера в json
Конструкция pm.expect(json.count).eql(expectedCount);
уже должна быть Вам знакома из предыдущего раздела. Мы снова сравниваем два значения. Ничего нового.
Количество элементов в массиве entries
должно быть равно количеству, указанному в count
Реализация этого сценария так же базируется на предыдущих элементах. Нам понадобиться получить json представление ответа сервера и получить размер массива entries
. Выглядит это следующим образом:
pm.test('Response \'entries\' field must have expected size', () => {
var json = pm.response.json();
var count = json.count;
var entriesCount = json.entries.length;
pm.expect(count).eql(entriesCount);
});
var json = pm.response.json();
- получаем json представление тела ответа сервераvar count = json.count;
- получаем значение поляcount
var entriesCount = json.entries.length;
- получаем значение размера массиваentries
. Напомню, по-скольку мы работаем с javascript, массивы javascript имеют свойствоlength
, которое хранит его размер. Чем мы в данном примере и воспользовалисьpm.expect(count).eql(entriesCount);
- ну и наконец, ещё один assert
Все элементы массива entries
должны иметь ссылки, использующие протокол https
Последний тестовый сценарий мы можем реализовать несколькими способами. Взглянем на данные в ответе сервера:
{
"count": 1425,
"entries": [
{
...
"HTTPS": true,
...
"Link": "https://www.adoptapet.com/public/apis/pet_list.html",
...
},
Мы можем организовать проверку одним из двух способов:
- либо мы анализируем URL’ы на предмет используемого протокола,
- либо, проверяем метаинформацию в поле
HTTPS
Предлагаю пойти по простому пути и написать тестовый сценарий, который соответствует второму способу. Это будет выглядеть следующим образом:
pm.test('Response \'entries\' use https', () => {
var json = pm.response.json();
var nonSecuredEntries = json.entries.filter((el) => {
return el.HTTPS == false;
});
pm.expect(nonSecuredEntries.length).eql(0);
})
где
var json = pm.response.json();
- получаем json тела ответа сервераvar nonSecuredEntries = json.entries.filter((el) => { return el.HTTPS == false; });
- фильтруем элементы массиваentries
по признакуHTTPS == false
pm.expect(nonSecuredEntries.length).eql(0);
- ну и наконец проверяем, что наш массивentries
не содержит ссылок, использующих не защищённый протокол
Вот как это выглядит в Postman:
Запускаем тесты
Чтобы выполнить наши тесты, достаточно выполнить сам запрос и результаты тестов будут отображены в разделе ответа сервера.
В нашем случае, это будет выглядеть следующим образом:
Мы описали 4 тестовых сценария. Каждому из них дали собственное наименование. Именно эти 4 сценария, поимённо, выведены в результатах.
Мы так же видим, что последний сценарий не пройден. Там, где мы ожидали увидеть 0 элементов с http
протоколом, нашлось аж 92 таких элемента. Тест резонно упал.
Функциональное тестирование
Тесты, которые мы составили, это обычные API тесты или функциональные тесты. Они оперируют API’ями на живых системах и являются простым способом организовать полу-автоматическую проверку работоспособности Ваших API’ев.
Почему полу-автоматическую? Потому что при текущем подходе, нам каждый раз нужно выполнять запуск выполнения запросов в Postman, для того, чтобы проверить работу тех или иных API.
А как этот процесс можно улучшить?
Для ответа на этот вопрос, у меня заготовлено два подхода.
Коллекция как набор тестов
Как уже было сказано выше, запросы в Postman можно группировать в папки и под-папки в коллекциях. Так почему бы не воспользоваться этим и не создать отдельные коллекции с тестовыми сценариями?
Пример:
На изображении выше, видно, что запросы в коллекции сгруппированы по сценариями. Есть некоторый гипотетический Audit Service
, для которого мы проверяем 2 сценария - сценарий регистрации нового клиента и управления данными аудита.
При этом, Postman позволяет выполнять все запросы коллекции в заданном порядке, буквально, одним кликом. В меню каждой коллекции есть пункт - Run collection
, нажатие на который и приводит к прогону абсолютно всех запросов и их тестов выбранной коллекции.
Коллекция как автоматизированный набор тестов
В случае второго подхода, мы так же, оперируем коллекцией Postman, но - тесты прогоняем уже не сами, а, на каком-нибудь CI.
Есть такой прекрасный инструмент - Newman. Это инструмент командной строки, то есть, не имеет графического интерфейса пользователя (GUI) и позволяет запускать коллекции Postman.
Как, в этом случае, будет выглядеть процесс работы с тестами Postman?
- Разработчик тестов экспортирует коллекцию Postman во внешний файл (обычно это json со специальным содержимым)
- Добавляет полученный файл в репозиторий с тестами
- Для тестируемого приложения, на CI, создаётся отдельный шаг или отдельный план в котором выгружается из репозитория файл с тестами и передаётся на исполнение Newman
Заключительная часть
Я надеюсь после прочтения этой статьи Вы нашли для себя нечто новое и осознали, что Postman более не является простой API тыкалкой и пинговалкой.
Нынче, Postman плавно становится мощным инструментом в руках разработчиков. Я сам использую его возможности для создания функциональных тестов для проведения dev-тестирования своих сервисов и их API’ев. И могу сказать, что это прекрасный способ быстро отловить ошибки в Ваших сервисах, по мере их реализации.