Принцип хорошего автотеста — «Подготовь себе данные сам. Не надейся, что они уже существуют». Такой тест можно прогнать на любом стенде, даже пустом. Сам себе всё подготовил, прогнал тест, а потом ещё почистил за собой.
В Postman тоже есть возможность подготовить себе данные для запроса. Причем это можно использовать не только для автоматизации, но и для ручного прогона. Удобно же, когда можно запустить конкретный запрос на конкретный метод, а он отработает успешно хоть на пустой базе, хоть на заполненной.
Подготовка данных делается через функцию pm.sendRequest() в pre-request скриптах, и в этой статье я покажу, как её использовать. Показывать буду в стиле «бери и повторяй» с примерами на бесплатной системе Users.
Содержание
Как отправить запрос в pre-request
Запрос строится следующим образом (пример из документации). Сначала мы прописываем сам запрос в переменной postRequest, а потом вызываем его через функцию sendRequest:
// Example with a full-fledged request
const postRequest = {
url: 'https://postman-echo.com/post',
method: 'POST',
header: {
'Content-Type': 'application/json',
'X-Foo': 'bar'
},
body: {
mode: 'raw',
raw: JSON.stringify({ key: 'this is json' })
}
};
pm.sendRequest(postRequest, (error, response) => {
console.log(error ? error : response.json());
});
Попробуем на Users. Допустим, что мы тестируем метод getUser — получение информации по пользователю. Подготовим наш запрос (если вы раньше не сталкивались с Postman, посмотрите видео «Как отправить REST-запрос за 5 минут» и статью «Что такое JSON»):
Тип метода — POST
URL — http://users.bugred.ru/tasks/rest/getuser
Body в json:
{
"email": "test_habr_1@mail.com"
}
Но, чтобы информацию получить, пользователя вначале нужно создать. А пока мы получаем ошибку: «Пользователь не найден» (если хотите пройти шаги с нуля, то придумайте свой уникальный email, которого пока в системе нету):
Давайте сделаем так, чтобы запрос всегда проходил успешно. То есть перед вызовом метода сначала создадим пользователя.
Самый простой путь — через метод doregister. Если это делать через обычный запрос, а не pre-request, он будет выглядеть так:
Тип метода — POST
URL — http://users.bugred.ru/tasks/rest/doregister
Body в json:
{
"name": "Хабр 1",
"email": "test_habr_1@mail.com",
"password": "1"
}
Теперь перепишем его в pre-request:
const postRequest = {
url: 'http://users.bugred.ru/tasks/rest/doregister',
method: 'POST',
body: {
mode: 'raw',
raw: JSON.stringify({
email: "test_habr_1@mail.com",
name: "Хабр 1",
password: 1
})
}
};
pm.sendRequest(postRequest, function (err, res) {
console.log(err ? err : res.json().message);
});
Добавляем этот код во вкладку «Scripts → Pre-request» и снова нажимаем «Send». И вуаля, запрос выполнен успешно!
Но постойте… А что будет, если я повторно отправлю запрос? И что будет, если pre-request упадет? Давайте проверим!
Отправляем запрос повторно — он проходит успешно. А что было с pre-request? Можно проверить в консоли. Открываем её:
И видим, что наш запрос сначала вызвал метод doregister, который вернул в Body ошибку «email уже существует», а потом всё равно пошел вызов getuser. Значит, вызов запроса не зависит от ошибок в pre-request… Или зависит?
Users — тестовая система, в которой на любой запрос тебе вернется код 200. Это можно проверить, дергая doregister отдельно. При попытке сломать запрос:
Поменять URL, удалив последнюю букву — url: 'http://users.bugred.ru/tasks/rest/doregiste'
Поменять тип запроса на GET (а там все методы только через POST работают, напомню, что система тестовая)
…
Мы всегда получаем в ответе «200 ОК». Попробуем всё же сломать систему. Для этого в URL подставим что-то совсем другое, другое API, которое умеет возвращать ошибки. А тело оставим от Users, как раз на нем и свалится.
Я поменяла URL на вызов JIRA и записала это в виде второй переменной (postRequest2). То есть просто добавила в pre-request такой блок кода:
const postRequest2 = {
url: 'https://testbase.atlassian.net/rest/api/3/issue/TEST-18750',
method: 'POST',
body: {
mode: 'raw',
raw: JSON.stringify({
email: "test_habr_1@mail.com",
name: "Хабр 1",
password: 1
})
}
};
pm.sendRequest(postRequest2, function (err, res) {
console.log(err ? err : res.json().message);
});
Отправляем запрос — ага, ошибочка!
Так что учтите, что таким образом можно дергать только идемпотентный метод, который не будет падать при повторном вызове.
Если у вас запрос на создание падает, когда «такая сущность уже есть в базе», то нужно будет оборачивать вызов во всякие условия «если сущность уже есть, пропусти, если нет, создай…».
Но этот случай выходит за рамки нашей статьи. Сейчас наша цель — просто научиться использовать pre-request скрипты в базовом варианте. И понимать, что с ними будет в том или ином случае. И один запрос мы отправлять уже научились!
Как отправить несколько запросов в pre-request
Продолжаем изучать метод getUser. У него в ответе много разных полей — вот было бы здорово, если бы они все были заполнены на тестовом юзере. А как это сделать?
Вообще в Users есть метод createuser, который решает эту проблему за один запрос. Но предположим, что такого метода нет. И единственный вариант — сначала пользователя создать через doregister, а потом заполнить все поля через fullupdateuser.
Кажется, что это будет легко. Просто напишем 2 предварительных запроса подряд:
pm.sendRequest(req1, done);
pm.sendRequest(req2, done);
Но тут есть проблема. Функция pm.sendRequests асинхронна. Это значит, что она сразу отправит оба запроса, а не будет дожидаться, когда отработает req1, чтобы запустить req2. И тогда второй запрос сломается, ведь первый ещё не отработал, пользователь ещё не создан, кого тогда обновлять?
Если мы хотим, чтобы запрос req2 отработал строго после выполнения req1, необходимо вызвать его внутри sendRequest по req1 (источник этого способа):
pm.sendRequest(req1, function () {
pm.sendRequest(req2, done);
});
Давайте так и сделаем! Переписываем pre-request скрипт:
const req_1_create = {
url: 'http://users.bugred.ru/tasks/rest/doregister',
method: 'POST',
body: {
mode: 'raw',
raw: JSON.stringify({
email: "test_habr_1@mail.com",
name: "Хабр 1",
password: 1
})
}
};
const req_2_update = {
url: 'http://users.bugred.ru/tasks/rest/fullupdateuser',
method: 'POST',
body: {
mode: 'raw',
raw: JSON.stringify({
email: "test_habr_1@mail.com",
name: "Васенька",
birthday: "01.01.1900",
gender: "m",
date_start: "11.11.2000",
hobby: "Валяться на диване",
name1: "Тестовый, ясен пень",
surname1: "Иванов",
fathername1: "Петров",
cat: "Маруся",
dog: "Ушастый",
parrot: "Васька",
cavy: "Кто ты?",
hamster: "Хомяк",
squirrel: "Белая горячка к нам пришла",
phone: "333 33 33",
adres: "адрес 1",
inn: "123456789012"
})
}
};
pm.sendRequest(req_1_create, function () {
pm.sendRequest(req_2_update, function (err, res) {
console.log(err ? err : res.json().message); })
});
Отправляем запрос — да! В ответе у нас уже имя «Васенька», то есть исправленные данные:
Итого
В Postman есть много полезных функций, которые упрощают вам работу с API. Одна из таких функций — pm.sendRequest(), которая подготавливает тестовые данные для успешного прогона метода.
Она очень полезна, если вызываемые «предварительно» методы идемпотентны и не падают при повторном запуске. Если у вас есть связанный функционал, не надо каждый раз ломать голову «как подготовить данные, чтобы этот метод сработал?».
Вы можете сделать отдельную коллекцию (папку с запросами), которые будут запускаться друг за другом, и прогонять её. А можете использовать pm.sendRequest() и прописать все предварительные шаги внутри конкретного метода. Дальше уже выбор за вами.
Но, используя sendRequest, помните — эта функция асинхронна! Так что если нужно вызвать один запрос, и только потом второй, используйте такую конструкцию:
pm.sendRequest(req_1, function () {
pm.sendRequest(req_2, function (err, res) {
console.log(err ? err : res.json().message); })
})
На этом на сегодня всё, увидимся в следующий раз =)
PS — больше полезных статей ищите в моем блоге по метке «полезное». А полезные видео — на моем youtube-канале