Автоматизации REST API посредством Postman

Добрый День! Меня зовут Галактион, я — QA, в этой статье я собираюсь поделиться с Вами опытом автоматизации API посредством Postman, используя язык программирования — JavaScript.
Проект, о котором пойдет речь — это региональный портал государственных и муниципальных услуг, в котором интегрированы следующие сервисы (все перечислять не буду, т.к. их множество):

  • ЕМИАС (Единая медицинская информационно-аналитическая система), предназначенная для вызова и записи к врачу;

  • Запись в МФЦ;

  • Электронный дневник;

  • «ЕКЖИП» — Единая книга жалоб и предложений;

  • Платежи ГИБДД;

  • График отключения горячей воды и т.д.

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

Декомпозиция

Декомпозиция

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

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

Генерация основного токена

Генерация основного токена

pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
});

  postman.setGlobalVariable("GeperidzeGO_token_prod", responseBody);

На первой и второй строках проверяем статус-код 200 от сервера. На пятой строке я прошу, чтобы тело ответа — «responseBody» записалось в переменную глобального окружения под названием «GeperidzeGO_token_prod».
Snippets — это шаблоны, которые по умолчанию находятся под кнопкой «Send». Каждый шаблон можете доработать под себя.

Шаблоны готовых скриптов

Шаблоны готовых скриптов

Далее необходимо перейти в раздел Environments — Global, здесь записана переменная, которая будет хранить токен. Ps: Можете создать отдельное окружение.

Переменные глобального окружения

Переменные глобального окружения

В последующих запросах будем обращаться к глобальным переменным через двойные фигурные скобки »{{}}».
В запросы подставляем глобальную переменную в заголовок запроса по ключу авторизации

Обращение к токену

Обращение к токену

Предлагаю разобрать пример коллекции ЕМИАС — сервис записи к врачу. Для того, чтобы записаться к врачу, нам необходимо отправить следующие запросы.

Запись к врачу

Запись к врачу

Первым делом, по уже знакомому принципу, необходимо сгенерировать ЕМИАС — токен и вывести его в переменную для дальнейшего использования.

Генерация токена интегратора

Генерация токена интегратора

var jsonData = JSON.parse(responseBody);
postman.setGlobalVariable("emias_token_edinichki", jsonData.***);

pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
});

В первой строке я ввожу переменную jsonData для парсинга тела ответа. JSON. parse () обрабатывает строку в формате JSON, при ошибке парсинга будет выведена ошибка, что был нарушен синтаксис. responseBody — тело ответа (целиком). В конце второй строки я заблюрил ключ, по которому ответ предоставляет токен. А обращаемся к ключу по имени нашей переменной и через точку пишем имя ключа, например, «jsonData.key».

Далее отправляется запрос по конкретному врачу для получения открытых к записи дней недели (предварительно у меня выбрана специализация — хардкод, т.к. специализация тестовая).

Поиск первого свободного дня у первого подходящего врача

Поиск первого свободного дня у первого подходящего врача

console.log('Start test case');
pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
});

console.log('Test case finished, try to set date');

var jsonData = JSON.parse(responseBody);

var items = jsonData.items[0];
var doctors = items.doctors;
for (var i = 0; i < doctors.length; i++) {
    var doctor = items.doctors[i];
    console.log('Processing doctor: ' + doctor.name);
    for (var j = 0; j < doctor.schedule.length; j++) {
        var sched = doctor.schedule[j];
        console.log('Processing schedule: ' + sched.date);
        if (sched.count_tickets > 0) {
            console.log('Find available day, trey to set global variable');
            postman.setGlobalVariable("available_date", sched.date.substr(0, 10));
            postman.setGlobalVariable("doctor_id", doctor.id)
            postman.setGlobalVariable("lpu_code", doctor.lpu_code)
            return;
        }
    }
}

В 10-ой строке я ввожу переменную items, где меня интересует первый открытый день для записи. В 11-ой строке я ввожу переменную doctors, для получения списка доступных врачей. В 12 строке я запускаю цикл, который проходит по каждому доступному врачу. Далее — на 15-ой строке я запускаю вложенный цикл, в котором хочу получить все расписания свободных дней для записи. На 18-ой строке я уточняю, есть ли наличие свободных талонов, если все условия выполняются, то я прошу записать данные в переменные глобального окружения.

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

Поиск первого свободного талончика

Поиск первого свободного талончика

pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
});

var jsonData = JSON.parse(responseBody);

var schedule = jsonData.schedule;
for (var i = 0; i < schedule.length; i++){
        if (schedule[i].access == true){
            postman.setGlobalVariable("ticket_time", schedule[i].time)
        }
}

В 8-ой строке я запускаю цикл, по которому прошу найти доступную запись и записать ее в переменную «ticket_time».

Далее мы отправляем POST-запрос для записи к врачу, в теле передаю необходимые переменные.

Запись к врачу, пост-запрос - тело

Запись к врачу, пост-запрос — тело

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

Запись к врачу, пост-запрос - скрипт

Запись к врачу, пост-запрос — скрипт

pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
});

var jsonData = JSON.parse(responseBody);
postman.setGlobalVariable("doctor_entry_id", jsonData.entry_id);

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

Удаление записи

Удаление записи

Таким образом, весь сценарий состоит из 6 минимальных запросов. Скорость прогона данной папки — 5 секунд, в случае если проблем с сервисом нет, и отсутствуют раннее созданные записи, если есть ошибки, то запросы будут до тайм-аутов, которые устанвливают разработчики. В правилах хорошего тона — очищать за собой тестовые данные.

Запуск коллекции. Тапаем по многоточию/мультивыбору, кому как нравится — тапаем по «Run folder». Ps: Аналогично прогоняется вся директория «Run collection». Ограничений у «Run folder» по количеству запусков нет, а у «Run collection» — 25 запусков/месяц — бесплатно.

8080e5a0f3141c467b9df35f181505e5.pngRunner

Runner

Не забудьте поставить чек-бокс — для парсинга тел ответа.

Результат прогона

Результат прогона

API тесты более стабильные по сравнению с GUI — их легче писать и поддерживать. Такая коллекция сокращает время при регрессах, ее можно ставить на ежедневный прогон с помощью раздела Monitors.

Монитор

Монитор

Если Вы ручной тестировщик и планируете развиваться в авто — API-тесты могут стать Вашим первым шагом для миграции в AQA.
Один из минусов — прогон коллекций в бесплатной версии Postman ограничен до 25 ранов в месяц, поэтому при наличии времени коллекцию можно перенести в Python — используя фреймворк Pytest и библиотеку Requests.

© Habrahabr.ru