- Особенности GET
- Сценарий 1 — Получение всех заказов
- Сценарий 2 — Получение отфильтрованных заказов
- Сценарий 3 — Фильтрация по нескольким параметрам
Начало работы
Подробности о предварительных требованиях, установке и настройке уже обсуждались в предыдущих частях туториала.
Тестируемое приложение
Продолжаем работать с бесплатными тестовыми API restful-ecommerce демо-приложения магазина, проект выложен на GitHub. Проект может быть установлен локально с помощью node или docker. В нем созданы несколько API, связанных с управлением заказами — создание, обновление, получение и удаление заказов.
Напомним, что такое GET-запрос
GET-запрос извлекает данные из указанного источника. Это наиболее часто используемый метод HTTP. Он не требует отправки тела запроса для получения данных из источника, однако в качестве заголовка могут потребоваться параметры для фильтрации, называемые Query Params
и Path Params
, чтобы отфильтровать и получить запись в нужном виде.
Запрос GET стандартно возвращает статус-код 200
вместе с запрошенными данными. В зависимости от Content-Type
данные могут быть получены в формате JSON или XML.
В следующем примере restful-ecommerce API есть 2 эндпойнта (далее конечные точки) API, которые мы сейчас будем тестировать.
- Конечная точка GET /
getAllOrders
— Получает все доступные заказы в системе
Этот API возвращает в ответ статус-код 200
, с данными о заказе в формате JSON.
Если такие заказы не найдены, возвращается код состояния 404, с сообщением «Заказ не найден !!!»
2. Конечная точка GET /getOrder
— Получение заказа с фильтром либо по id заказа, либо по id пользователя, либо по id продукта, либо по всем этим параметрам.
GET-запрос вернет код состояния 200
с отфильтрованным заказом в ответе, в противном случае вернет код состояния 404
с сообщением «No order found with the given parameter
«.
Приступим.
Сценарий тестирования 1 — Получение всех заказов
- Запускаем сервис для приложения restful-ecommerce
- Запускаем конечную точку GET
/getAllOrders
, чтобы получить все доступные заказы в системе - Проверяем, что в ответ получен код состояния
200
- Проверяем, что в ответ получены правильные данные
Примечание: Ранее мы уже создавали 4 заказа с помощью POST-запроса. Мы будем использовать получение тех же данных о заказах с помощью конечной точки GET /getAllOrders
Реализация теста
Создадим новый тестовый метод testShouldGetAllOrders()
в существующем тестовом классе HappyPathTests
.
Просто повторяю, что в части туториала по POST-запросам было создано два тестовых класса, HappyPathTests
и SadPathTests
, также был добавлен класс BaseTest
для конфигурирования и настройки Playwright.
@Test public void testShouldGetAllOrders() { final APIResponse response = this.request.get("/getAllOrders"); final JSONObject responseObject = new JSONObject(response.text()); final JSONArray ordersArray = responseObject.getJSONArray("orders"); assertEquals(response.status(), 200); assertEquals(responseObject.get("message"), "Orders fetched successfully!"); assertEquals(this.orderList.get(0).getUserId(), ordersArray.getJSONObject(0).get("user_id")); assertEquals(this.orderList.get(0).getProductId(), ordersArray.getJSONObject(0).get("product_id")); assertEquals(this.orderList.get(0).getTotalAmt(), ordersArray.getJSONObject(0).get("total_amt")); }
Результат запроса к API будет сохранен в переменной response
, которая определена для типа APIResponse
. GET-запрос будет отправлен с помощью this.request.get("/getAllOrders")
, который обработает GET-запрос и получит данные из системы.
Ответ будет получен с помощью метода response.text()
Playwright и сохранен в переменной responseObject
, имеющей тип JSONObject
(это класс библиотеки org.json
). Ниже приведен ответ, полученный в формате JSON для конечной точки GET /getAllOrders
.
{ "message": "Orders fetched successfully!", "orders": [ { "id": 1, "user_id": "3", "product_id": "331", "product_name": "Aerodynamic Cotton Bench", "product_amount": 416, "qty": 4, "tax_amt": 47, "total_amt": 1711 }, { "id": 2, "user_id": "2", "product_id": "331", "product_name": "Incredible Linen Keyboard", "product_amount": 716, "qty": 1, "tax_amt": 45, "total_amt": 761 }, { "id": 3, "user_id": "2", "product_id": "332", "product_name": "Gorgeous Concrete Bench", "product_amount": 900, "qty": 2, "tax_amt": 38, "total_amt": 1838 }, { "id": 4, "user_id": "2", "product_id": "331", "product_name": "Ergonomic Concrete Gloves", "product_amount": 584, "qty": 2, "tax_amt": 21, "total_amt": 1189 } ] }
Поскольку внешняя часть ответа представляет собой JSON-объект, значения сохраняются с помощью класса JSONObject
.
final JSONObject responseObject = new JSONObject(response.text());
Однако данные о заказе подтягиваются в виде массива JSON, поэтому данные о заказе хранятся в переменной ordersArray
.
final JSONArray ordersArray = responseObject.getJSONArray("orders");
Наконец, будут выполнены ассерты, проверяющие, что GET /getAllOrders
возвращает статус-код 200
. Метод response.status()
вернет статус-код.
Переменная responseObject
хранит полученный ответ, поэтому мы получим поле message
из этого JSON-объекта, чтобы проверить, что оно содержит текст «Orders fetched successfully!
«
В предыдущей части туториала мы использовали класс OrderData
для генерации данных о заказах с помощью DataFaker и Lombok, а в тестах POST-запроса мы объявили List<OrderData>
с переменной orderList
. Этот же объект будет вызываться в ассерте для проверки целостности полученных данных о заказе. Ниже приведен JSON-массив, который извлекается в ответ.
"orders": [ { "id": 1, "user_id": "3", "product_id": "331", "product_name": "Aerodynamic Cotton Bench", "product_amount": 416, "qty": 4, "tax_amt": 47, "total_amt": 1711 }, { "id": 2, "user_id": "2", "product_id": "331", "product_name": "Incredible Linen Keyboard", "product_amount": 716, "qty": 1, "tax_amt": 45, "total_amt": 761 }, { "id": 3, "user_id": "2", "product_id": "332", "product_name": "Gorgeous Concrete Bench", "product_amount": 900, "qty": 2, "tax_amt": 38, "total_amt": 1838 }, { "id": 4, "user_id": "2", "product_id": "331", "product_name": "Ergonomic Concrete Gloves", "product_amount": 584, "qty": 2, "tax_amt": 21, "total_amt": 1189 } ]
Мы будем проверять первый объект из массива order
.
{ "id": 1, "user_id": "3", "product_id": "331", "product_name": "Aerodynamic Cotton Bench", "product_amount": 416, "qty": 4, "tax_amt": 47, "total_amt": 1711 }
Следующие строки кода получат из объекта значения user_id
, product_id
и total_amt
и, соответственно, используют данные, которые были переданы с помощью переменной orderList
(данные генерируются во время выполнения с помощью Datafaker и Lombok).
assertEquals(this.orderList.get(0).getUserId(), ordersArray.getJSONObject(0).get("user_id")); assertEquals(this.orderList.get(0).getProductId(), ordersArray.getJSONObject(0).get("product_id")); assertEquals(this.orderList.get(0).getTotalAmt(), ordersArray.getJSONObject(0).get("total_amt"));
Выполнение теста
Сначала нам нужно убедиться, что приложение restful-ecommerce запущено и работает. Ознакомьтесь с шагами здесь, чтобы запустить приложение на вашей локальной машине.
Мы будем выполнять POST-запрос (сгенерированный в соответствующей части туториала) и GET-запрос, используя файл testng.xml
ниже. POST-запрос сгенерирует заказы, а GET-запрос получит заказы и выполнит необходимые ассерты.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="Restful ECommerce Test Suite"> <test name="Testing Happy Path Scenarios of Restful E-Commerce APIs"> <classes> <class name="io.github.mfaisalkhatri.api.restfulecommerce.HappyPathTests"> <methods> <include name="testShouldCreateNewOrders"/> <include name="testShouldGetAllOrders"/> </methods> </class> </classes> </test> </suite>
Скриншот из IntelliJ IDE показывает, что выполнение теста прошло успешно и заказы были получены успешно.
Сценарий тестирования 2 — Получение отфильтрованных заказов по order_id
- Запустить службу для приложения restful-ecommerce
- Запустить конечную точку GET
/getOrder
для получения фильтрации заказов поorder_id
с помощью параметраQuery
- Проверить, что в ответ получен код состояния
200
- Проверить, что в ответ получены правильные данные
Реализация теста
Создадим новый тестовый метод testShouldGetOrderUsingOrderId()
и реализуем в нем тестовый сценарий 2.
@Test public void testShouldGetOrderUsingOrderId() { final int orderId = 1; final APIResponse response = this.request.get("/getOrder", RequestOptions.create().setQueryParam("id", orderId)); final JSONObject responseObject = new JSONObject(response.text()); final JSONArray ordersArray = responseObject.getJSONArray("orders"); assertEquals(response.status(), 200); assertEquals(ordersArray.getJSONObject(0).get("id"), orderId); assertEquals(responseObject.get("message"), "Order found!!"); }
У нас уже есть несколько заказов, созданных в системе. Мы будем получать заказ с order_id = 1
Для получения заказа с фильтром order_id
нам нужно указать order_id
в качестве параметра запроса. Это можно сделать с помощью следующей строки:
Параметр запроса передается с помощью метода setQueryParam()
из интерфейса RequestOptions
в Playwright. В качестве параметра в метод setQueryParam()
нужно передать имя параметра и его требуемое значение.
Далее нам нужно обработать объект ответа и получить его в формате JSON. Метод response.text()
возвращает ответ API в формате String
. Эта строка будет преобразована в обработанный объект JSON с помощью класса JSONObject
из библиотеки org.json
.
Обработанный объект JSON будет в дальнейшем использоваться для выполнения ассертов. Здесь не будет проверок целостности данных, мы только проверяем, что объект ответа имеет тот же order_id
, который мы указали в запросе, и в ответе возвращается статус-код 200
.
Далее мы проверяем, что поле message в ответе имеет текст «Заказ найден!!!
»
Выполнение теста
Добавим этот метод в тот же файл testng.xml
, перезапустим приложение restful-ecommerce, чтобы у нас было свежее приложение без данных, и запустим все тесты снова.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="Restful ECommerce Test Suite"> <test name="Testing Happy Path Scenarios of Restful E-Commerce APIs"> <classes> <class name="io.github.mfaisalkhatri.api.restfulecommerce.HappyPathTests"> <methods> <include name="testShouldCreateNewOrders"/> <include name="testShouldGetAllOrders"/> <include name="testShouldGetOrderUsingOrderId"/> </methods> </class> </classes> </test> </suite>
Следующий скриншот выполнения теста показывает, что тесты были выполнены успешно и заказы были получены в соответствии со сценарием.
Тестовый сценарий 3 — Получение фильтрации заказов по нескольким параметрам запроса
- Запустить сервис для приложения restful-ecommerce
- Запустить конечную точку GET
/getOrder
для получения фильтрации заказов по параметрам запросаorder_id
,product_id
иuser_id
- Проверить, что в ответе получен код состояния
200
- Проверить, что в ответе получены правильные данные
Реализация теста
Реализация этого тестового сценария практически такая же, как и для тестового сценария 2. Единственным дополнением здесь будет добавление параметров запроса product_id
и user_id
в тестовый метод.
Новый тестовый метод testShouldGetOrdersUsingOrderIdProductIdAndUserId()
добавляется в существующий класс HappyPathTests
.
@Test public void testShouldGetOrdersUsingOrderIdProductIdAndUserId() { final int orderId = 2; final String productId = "332"; final String userId = "2"; final APIResponse response = this.request.get("/getOrder", RequestOptions.create() .setQueryParam("id", orderId) .setQueryParam("product_id", productId) .setQueryParam("user_id", userId)); final JSONObject responseObject = new JSONObject(response.text()); final JSONArray ordersArray = responseObject.getJSONArray("orders"); assertEquals(response.status(), 200); assertEquals(responseObject.get("message"), "Order found!!"); assertEquals(ordersArray.getJSONObject(0).get("id"), orderId); assertEquals(ordersArray.getJSONObject(0).get("product_id"), productId); assertEquals(ordersArray.getJSONObject(0).get("user_id"), userId); }
В этом тестовом методе setQueryParam
вызывается три раза, чтобы передать необходимые параметры.
Остальная часть реализации, связанная с разбором ответа и проверкой статус-кода и сообщения, остается прежней. Кроме того, в метод добавлены ассерты, проверяющие, что полученная в ответе информация о заказе имеет заданные order_id
, product_id
и user_id
. Этот ассерт гарантирует, что были получены правильные данные о заказе в соответствии с параметрами запроса.
Выполнение теста
Следующий результат выполнения теста из IntelliJ показывает, что детали заказа в соответствии с параметрами запроса были получены успешно.
Резюме
Запросы GET позволяют получить необходимые данные с указанного ресурса. Это наиболее часто используемый метод HTTP. Обычно он возвращает данные в ответ с кодом состояния 200. GET-запросы также могут учитывать необходимые фильтры с помощью параметров запроса или параметров пути для запроса данных.
При тестировании GET-запросов нам необходимо проверять правильность данных, полученных в ответе. Эта проверка будет проводиться для всех данных, получаемых сразу или в соответствии с заданными параметрами запроса.
Playwright предоставляет метод get() в интерфейсе APIRequestContext, который можно использовать для получения данных. Также поддерживаются определенные параметры запроса: заголовки, параметры запроса и т. д.
***