Всем привет! Сегодня я расскажу о том, как мы тестируем Rest API в SM 2.0 с помощью инструмента Postman. И сделаю это на примере реальной задачи — посмотрим сценарий пользователя (как оформляется заказ у нас на сайте), посмотрим, как это работает все изнутри, пару слов скажу о REST-запросах, расскажу про Postman. Далее мы перейдём в сам инструмент, посмотрим окружение, интерфейс, далее разберём исходные данные и приступим к решению самой задачи, и в конце немного расскажу про автотесты.  Наша задача – создать один заказ с двумя товарами разными методами и способами получения (МСП). Первый товар – тренажер эллиптический. Он будет заказан на самовывоз из первого доступного магазина. Я выбрала город Воронеж, потому что там всего 5 магазинов, и выбирать так было проще. Оплата у нас будет онлайн на сайте. Второй товар – ветровка, будет оформлена доставка курьером на адрес через подсказку от GeoGate (может быть, вы видели, когда создаёте заказ на доставку, он предлагает ввести улицу, вы можете несколько букв ввести, и получите подсказку). Оплата будет при получении курьеру. Очень важно! Чтобы задача была решена корректно, необходимо убедиться в том, что самовывоз 1 товара доступен и доставка курьером для 2 товара тоже доступна. Как происходит заказ? Человек заходит на сайт, добавляет первый товар, добавляет второй товар, затем нажимает на корзину, переходит в нее, начинает оформлять заказ. Первый товар будет на самовывоз из первого доступного магазина, второй товар будет на доставку. Затем нажимаем “Далее”, переходим на пункт оплаты, выбираем оплату и нажимаем “Далее”. Там потом высвечивается, кто будет заказывать, и мы нажимаем “Отправить заказ”. Потом просто мы сделаем проверку заказа: зайдем в “Личный Кабинет”, “Мои заказы” и удостоверимся, что эти заказы появились, и в них товары, которые мы выбрали. Как это работает изнутри? Пользователь заходит на сайт, сайт запрашивает каталог товаров, каталог отображается на сайте, и сайт уже показывает каталог пользователю. Пользователь выбирает товар, сайт кладет выбранный пользователем товар в корзину, отображается, что товар лежит в корзине, и это показывается пользователю. Потом пользователь оформляет заказ, нажимает на кнопку “Доставка”, сайт изменяет режим на “Доставку”, это где у нас radio button’ы “Доставить” или “Самовывоз”, OrderGate спрашивает, есть ли в наличии этот товар, и если приходит положительный ответ, то все хорошо.  Затем спрашиваем, на какие адреса доступна доставка, и нам отвечают, на какие именно, и сайт отображает список доступных адресов. Пользователь выбирает адрес, сайт отображает его, пользователь подтверждает заказ, сайт отправляет в OrderGateзапрос с подтверждением заказа, в системе остатков резервируется этот товар, чтобы не было никаких казусов.  После этого резерв подтверждается, заказ отправляется на обработку, и пользователю открывается страница “Спасибо за заказ”. Также мы на сайте для быстроты и удобства сохраняем последний адрес, который выбирал пользователь. Собственно говоря, все эти стрелочки – это запросы, то есть мы отправляем запрос на тот или иной пункт нашей диаграммы, и это у нас REST-запросы. Существует несколько видов REST-запросов. Одни из самых популярных – это Get, Post, Deleteи Update Put, самые популярные из которых – Getи Post, мы их чаще всего используем. Различие в том, что Get – запрос на получение или передачу информации, Postидет с телом, то есть мы можем какую-то информацию отправить — это запрос на регистрацию или добавление.  Чтобы протестировать, я выбрала инструмент POSTMAN, потому что мне показалось, что он очень удобный и простой в использовании. Перейдем в POSTMAN. Расскажу про интерфейс. Здесь есть окружение – глобальное и локальное, которое мы можем создавать самостоятельно. Я создала три окружения, но работаю только на тестовом uatSM. Чтобы переключаться между окружениями, можно выбрать галочку, и тогда вы будете работать в этом окружении. Справа вверху мы видим, что окружение сейчас для разработчиков. Выбираем uatSM, появляется галочка.  Плюс этих окружений в том, что у нас есть еще коллекции, которые создаются отдельно от окружения. В коллекциях мы можем сохранять различные запросы, допустим, у меня очень много запросов, которые я могу потом соединить в цепочку запросов. Эти запросы можно использовать на различных окружениях. Допустим, я сейчас в uatSM их тестирую, делаю запросы, потом я могу переключиться на другое окружение, и те же самые запросы выполнить на другом окружении.  В окружении есть параметры, которые мы можем задавать вручную: вводим название переменной и инициализируем ее. Расскажу еще про коллекции. У меня есть две коллекции – basket и test. Test я просто сделала для того, чтобы протестировать всякие разные запросы, которые мне понадобятся, а basket – та самая коллекция, в которой мы будем сегодня работать. Можно не вручную вызывать каждый запрос, а сделать Run Collection. Открывается Runner, который позволяет выполнять запросы автоматически в той последовательности, в которой вы сами можете их расположить. Сейчас у меня все по порядку, как мне нужно, чтобы все работало корректно. Здесь можно также создавать задержку выполнения запроса в миллисекундах, сохранять ответы и запускать саму коллекцию. Теперь покажу, как это все работает. Чтобы решить нашу задачу, нам нужно определить сценарий запросов. Сначала мы делаем очистку корзины, если в корзине у нас какие-то товары лежат, мы их просто удаляем, чтобы они нам не мешали. Потом, по сценарию пользователя, мы добавляем первый и второй товары в корзину, оформляем первый товар, оформляем второй на доставку, выбираем оплату, отправляем заказ и проверяем его.  Справа вы можете видеть запросы, которые я использовала, так же они есть в том же самом порядке в этой коллекции. Проверим на сайте, в каком состоянии сейчас находится корзина. Сейчас мы будем решать эту задачу, не находясь на сайте, просто работая с POSTMAN’ом. Сейчас в корзине ничего не лежит, для наглядности добавим какой-нибудь товар в корзину. Можем видеть, что в корзине сейчас лежит один товар. Перейдем в POSTMAN и выполним нашу коллекцию. Здесь идут наши запросы, с правой стороны мы видим статус нашего запроса. Если у нас приходит 200, то запрос выполнен успешно. Так же мы видим время его выполнения и его размер. Посмотрим, что у нас все работает, все отлично, везде 200, корзина сейчас должна обновиться, и должны появиться два заказа. Корзина пустая, и у нас есть два последних заказа: 270-489 и 270-200. Вот у нас первый заказ, который на сайте 270-200, и второй заказ – 270-489. Теперь можем рассмотреть это поближе. Добавляем какой-нибудь товар в нашу корзину. Видим, что в корзине сейчас один товар. Выполним запрос по порядку. Первый запрос у нас идет Cancel – очистка корзины. У меня очень много появилось параметров, которые здесь есть, я сейчас обновлю все, чтобы можно было следить за статусом нашей работы. Про параметры в POSTMAN очень интересная тема: мы можем задавать изначально параметры как исходные данные. Чтобы работать, например, с нашим сайтом и чтобы это была именно наша корзина, мы должны задать URL – адрес нашего тестового сайта, в котором я сейчас работаю. Так же у нас есть Cookie, которое говорит нам о том, что это именно наша корзина. И два id продукта, с которыми мы будем работать: тренажер эллиптический и ветровка мужская.  То есть мы это изначально задаем, мы это знаем. Сохраняем наши параметры в окружении, и теперь мы будем по порядку выполнять запросы. В нашей корзине сейчас лежит один товар. Выполняем запрос Cancel– это post-запрос с телом, мы отправляем пустой объект, чтобы очистить корзину. Выполняем запрос, видим статус 200, все хорошо, приходит ответ в формате JSON. Проверяем, что у нас происходит на сайте. Здесь должен появиться 0, пустая корзина. Работает.  Отлично. Теперь мы должны добавить первый товар. Это запрос add_prod1 – post-запрос с телом. В теле мы указываем id товара, который мы хотим добавить, и его количество. Id товара мы берем отсюда, количество задаем 1. Фигурные скобки обозначают, что мы используем параметр. Также параметр можно использовать не только в теле, но и в самом адресе запроса, как, например, здесь мы URL используем и не пишем каждый раз, руками не вводим. Это тоже очень удобно, дальше будут запросы, в которых нужно много параметров вводить. Выполняем запрос, видим статус “200”, смотрим, что происходит на сайте.  Появился у нас один товар – тренажер эллиптический – как раз то, что нам нужно. Дальше мы добавляем второй продукт, и вот здесь у нас начинается самое интересное. Здесь он так же абсолютно ничем не отличается от предыдущего запроса, просто мы добавляем здесь второй продукт, потому что нам удобно выполнять запрос автоматически и не менять здесь id на другой. Но здесь мы используем вкладку testsи создаем переменные.  Чтобы создавать переменные, мы используем метод Set. Называем переменную bastetId и берем ее из ответа, который будет находиться здесь после выполнения запроса, и у нас она будет лежать в поле “Id”. Сейчас выполним запрос, и я покажу. Переменные, которые мы сейчас создали во вкладке test, появятся в нашем окружении автоматически.  Выполняем запрос, статус “200”, можем посмотреть, что у нас появились переменные, которые мы хотели создать, как раз id, версия и статус корзины. Например, basketIdсмотрим, здесь у нас id a2029f. Смотрим, что у нас добавилось basketId a2029f, то есть мы разобрали ответ нашего запроса и забрали из него то, что нам необходимо, а также сохранили это в наших переменных окружения. Посмотрим на сайте, что у нас произошло.  Сейчас у нас должно быть два товара – тренажер и ветровка. Все отлично. Далее, мы должны сделать запрос Full, то есть это идет полная корзина, в ответе нам приходит вся корзина, здесь мы сохраняем данные о статусе корзины, об id и версии, потому что сейчас мы переходим именно в ту самую корзину, в ту версию, с которой мы будем работать и оформлять заказ. Мы его уже выполнили, нам пришел статус “200”, также мы видим, что статус корзины поменялся на “В процессе”, до этого у нас был “Пересчет”, можем посмотреть, поменялась у нас версия, id остался таким же. На сайте по сути ничего не поменялось, мы просто перешли в корзину. Что дальше? Самовывоз. Чтобы выполнить запрос на самовывоз, надо сначала запросить доступность этого товара на самовывоз, то есть можем ли мы вообще его получить самовывозом. Поэтому сначала надо выполнить запрос в availability, это get-запрос, он без тела, но благодаря ему мы можем запомнить магазин, в котором мы хотим получить наш товар, также мы запомним id, который должен идти на самовывоз, количество и можем узнать, требуется ли предоплата.  Все это нужно для выполнения запроса pickup– это post-запрос, и мы это все запрашиваем, чтобы в параметре вставить полученные с предыдущего запроса параметры. То есть нам необходимо получить wareid– id нашего товара, количество, сколько мы хотим на самовывоз получить, и в каком магазине мы хотим забрать этот товар. Получается, вот у нас параметры, которые мы достаем после выполнения нашего запроса. На сайте у нас ничего не меняется, мы просто делаем необходимые нам подготовительные запросы.  Выполняем запрос. Пришел статус 200. Здесь у нас появились параметры на самовывоз, у нас появился магазин, это самый первый по списку, который есть, просто так удобно было. Покажу, как мы это все делали. Вот здесь storeIdмы видим, что availability приходит в массиве, и мы берем самый первый элемент. 895 у нас самый первый, потом идет 720, то есть мы берем просто самый первый магазин для быстроты, для удобства, а так можно любой выбрать.  Может ли прийти пустой массив в ответе?
Если нет точек самовывоза, у нас будет ошибка в дальнейшем, то есть здесь у нас не заполнится ничего, и дальше, когда мы начнем выполнять запрос pickup, у нас не будет storeId, мы просто остановимся, не сможем выполнить этот запрос.  Самой ошибки в запросе не будет, запрос просто возвращает то, что там есть. В availabilityобычно что-то приходит (приходит Noneтолько если в корзине ничего нет). В тесте мы из этого запроса забираем параметры, то есть, если у нас ничего нет в storeId, значит, нам ничего не придет, параметры не заполнятся, текущий запрос выполнится, а следующий, в котором понадобятся эти параметры, не выполнится, потому что у нас их нет.  Можно ли выбрать какой-то определенный магазин? 
Вы можете здесь в storeIdне просто брать первый по списку элемент, а можете указать, что нужен именно такой с определенным id, то есть именно этот магазин, который вам нужен. Тогда он заполнится именно в параметре. Можно в параметры забирать не отдельные элементы, а весь список (массив), но как дальше его использовать и интерпретировать для следующих запросов – другая история. Мы выполнили запрос availability, получили необходимые нам параметры, далее мы выполняем запрос на самовывоз. Это запрос post, здесь у нас есть тело, в котором мы отравляем id товара на самовывоз, отправляем его количество и storeId магазина, который мы выбрали (895 id у него). Также из этого запроса мы берем параметры. Мы смотрим id нашего заказа на самовывоз, смотрим paymentMethod, который мы выбрали “онлайн” для первого товара.  Вот у нас: первый товар – оплата онлайн на сайте, самовывоз. Получается, что мы сохраняем оплату и id. Выполняем запрос. Статус “200”, вот нам приходит ответ, отсюда мы забираем paymentMethod, который нам доступен. У нас доступно несколько методов: cashless– безнал, в магазине (in_store), в кредит (credit) и онлайн. Онлайн у нас есть, мы его выбираем. Теперь у нас в окружении переменных появились те самые параметры, которые мы сохранили. Посмотрим, что произошло на сайте. Сейчас у нас должен быть заказ на тренажер. Вот мы видим, что у нас один товар в магазине в городе Воронеж.  Смотрим, что далее. Далее мы должны выполнить запрос на доставку, то есть выбрать второй товар на доставку, но перед этим мы опять должны вызвать запрос на доступность этого товара, потому что наша корзина поменялась – у нас ушел один товар, возможно, стоимость доставки поменялась, и, скорее всего, это так. Поэтому мы делаем запрос availability_pickUP. На сайте у нас ничего нового не происходит, мы просто запрашиваем доступность. Это get-запрос без тела, но отсюда мы очень много параметров вытаскиваем.  Все потому, то для запроса deliveryнеобходимо очень много параметров в теле. То есть мы передаем туда стоимость доставки, лимит бесплатной доставки, номер дома, улицу, время, дату, нужна ли предоплата. В общем, мы передаем все вот эти параметры, которые нам необходимы. Поэтому здесь много параметров, которые мы сохраняем. Мы выполняем этот запрос, из этого запроса, тоже из массива, мы достаем различные значения полей.  Здесь у нас была интересная вещь с датой, потому что дата в запросах в формате двух чисел, то есть если у вас 7.09 2021 года, например, то в запросе она должна храниться в формате '0709’, а нам приходит просто ‘79’. Поэтому мы тут соединяли строки, добавляли нолики.  Выполняем запрос. Запрос выполнен, статус 200. Смотрим, что в окружении появились новые параметры, deliveryCost, например, freeDelivery, дата, время, timeSlotIdу нас появился.  Теперь, чтобы выполнить запрос доставки, нам понадобится еще дом и улица. Для этого мы выполним два вспомогательных запроса – street, чтобы его выполнить, это идет запрос с параметром, то есть мы здесь указываем те буквы, которые мы вводили на сайте, чтобы он вывел подсказку полностью “Улица Высоцкого”. Когда мы вводим кириллицей, сайт у нас сам исправляет на такие символы, это правило такое.  После того, как мы выполним этот запрос, мы должны сохранить параметры, которые нам придут, то есть, сохранить в переменные, чтобы использовать в запросе delivery. Выполняем запрос улицы. Приходит “улица Владимира Высоцкого”, смотрим, что у нас появилась эта улица. Все отлично. Теперь выполняем запрос дома, у нас идет пятый дом, и параметры, мы можем как вводить это все вручную здесь, так и указать вот здесь параметры самого запроса. StreetIdмы также указали параметром из предыдущего запроса, который мы получили вот отсюда.  Вот у нас streetId, он сохранился здесь, и отсюда он его подгружает в параметры для следующего запроса с помощью двойных фигурных скобок. Отсюда мы забираем параметр house – дом. Выполняем запрос, нам приходит номер дома, мы его сохраняем. Теперь у нас есть все параметры, которые необходимы для выполнения запроса delivery. Отсюда мы так же берем параметры, которые мы брали из запроса на самовывоз. Мы берем id этого заказа на delivery и также мы указываем, что мы хотим оплатить второй товар при получении курьеру. Указываем to_courier, выполняем запрос. Статус 200, у нас появились параметры курьеру, появился id заказа, и на сайте у нас есть 2 оформленных заказа.  Следующий пункт – нужно выбрать способ оплаты. То есть вот два оформленных заказа, далее мы просто должны выбрать оплату. Для этого нам необходимо выполнить запрос payment-info. Это post-запрос, он с телом. В этот запрос мы указываем массив с двумя объектами: для первого заказа и для второго заказа. Мы здесь указываем заказ на самовывоз и на доставку и указываем метод оплаты. Отсюда мы ничего не забираем, поэтому просто выполняем запрос. Приходит статус 200, смотрим, что у нас на сайте. Сейчас у нас, получается, должен выбрать оплату и перейти к третьему пункту (это контакты). Смотрим, что у нас первый заказ “Онлайн на сайте”, и второй заказ “Курьеру при получении”, как раз-таки то, что у нас было в задаче. Далее мы переходим к самому заказу. Отправляем туда свои данные и нажимаем “Перейти к оплате”. В POSTMAN’е мы делаем запрос submit – это post-запрос с телом. В тело мы передаем наши контакты. Мы не стали их параметризировать, просто забили текстом сами. Так же отсюда мы должны забрать два id наших заказов. Они приходят в виде строки, через запятую, мы берем сначала первый, потом второй. И присваиваем. Это для того, чтобы сделать эти 2 запроса на заказы и проверить, что именно наши товары там лежат, именно выбранного МСП. Отправляем запрос. Статус 200. Нам приходит просто строчка, здесь у нас два заказа через запятую. Этот мы сохраняем в параметр id1, второй мы сохраняем в параметр id2. Смотрим, сейчас у нас корзина должна обновиться. Все, заказ мы провели. Сейчас в личном кабинете появляется два наших заказа, которые мы оформили – 575 и 146. Вот они у нас здесь появились. Мы можем выполнить запросы, это get-запросы, мы можем их выполнить сами руками, и нам приходит в ответ больший такой JSON, где мы можем смотреть всю информацию о заказе. Мы видим, что это самовывоз, видим, что оплата “онлайн на сайте”, видим, что 895 магазин, который мы выбирали, то есть, самый первый по списку, мы видим, кто заказал этот товар, мы видим, что это за товар – тренажер эллиптический. Также здесь во вкладке testможно не только забирать и создавать переменные, но и тестировать, благодаря библиотеке chai, которая широко применяется для Javascript. Здесь, например, можно написать тест для проверки ответа, что у ответа статус “Ok, выполнено, 200”, что у него есть тело, что тело в формате JSON.  После того, как мы выполнили этот запрос, у нас вот этот тест отображается здесь. Мы видим check response зелененький, он прошел и никаких ошибок нет. Получается, что у нас пришел ответ “200”, что у нас есть тело и есть JSON, то есть все хорошо. Далее мы можем делать не один запрос, а несколько запросов и называть их как хотим. Здесь я проверила ответ, а здесь я проверяю тело. Как раз-таки здесь я проверяю параметры, которые посчитала нужным, чтобы понять, что это именно мой продукт, то есть у него именно нужный id, именно тот способ получения – самовывоз, именно нужный метод оплаты – онлайн, именно тот id на самовывоз. После выполнения этого запроса, я могу не сама заходить в ответ и в огромном массиве полей смотреть и выбирать, а могу просто указать это в коде, и он сам просто сверит и выдаст либо ошибку, либо “Все ок”. Видим, что здесь у нас check body зеленый, все отлично, прошло успешно.  Вот, собственно, и всё. Если у вас есть вопросы – пишите комментарии, с радостью отвечу!