REST Assured.Day 2

Продовжуємо вивчати документацію
Пишемо тест-кейси
Покриваємо автотестами створення та редагування бронювання

 

Документація REST API

Перед початком написання тестів необхідно ретельно вивчити документацію REST API. Без цього етапу неможливо скласти тест-кейси, які охоплюють всі сценарії використання. У документації ви знайдете всі необхідні ендпоінти, методи запитів, параметри та відповіді. Це дозволить вам глибоко зрозуміти, як взаємодіяти з API, і переконатися, що ваші тести повноцінно покриватимуть функціональність, за винятком помилок у роботі.

Складання тест-кейсів зі створення бронювання

Кроки:

Надіслати POST-запит на ендпоінт /booking із наданим тілом запиту.

Expected result:

    • Переконайтеся, що відповідь відповідає схемі, вказаній у файлі "bookingCreateResponseSchema.json".

JSON  файл https://drive.google.com/file/d/1XqDr83yj2XJ5GElKm_QSSmmbpf3fgIr0/view?usp=sharing

Кроки:

Надіслати POST-запит на ендпоінт /booking із наданим тілом запиту.

Expected result:

    • Код стану відповіді має бути 200 (OK).

Перевірка часу відповіді створення бронювання менше 3000 мс

Кроки:

Надіслати POST-запит на ендпоінт /booking із наданим тілом запиту.

Expected result:

      • Час відповіді має бути меншим за 3000 мс.

Кроки:

Надіслати POST-запит на ендпоінт /booking із наданим тілом запиту.

Expected result:

    • Значення поля "firstname" у тілі відповіді має бути "Jim".

Написання автотесту з тест-кейсів з коментарями

package activities;

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import io.restassured.response.ValidatableResponse;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static com.jayway.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.lessThan;


public class CreateActivities {
private String baseUrl = «https://restful-booker.herokuapp.com»; // Base URL for the API
private String basePath = «/booking»; // Base path

/**
* Test to verify that the created booking matches the schema
*/
@Test
@DisplayName(«Create Booking matches schema»)
public void test1() {

// Arrange
String body = «»»
{
«firstname» : «Jim», // Customer’s first name
«lastname» : «Brown», // Customer’s last name
«totalprice» : 111, // Total price of the booking
«depositpaid» : true, // Flag indicating whether deposit is paid
«bookingdates» : { // Booking dates
«checkin» : «2018-01-01», // Check-in date
«checkout» : «2019-01-01» // Checkout date
},
«additionalneeds» : «Breakfast» // Customer’s additional needs
}
«»»;

// Act
ValidatableResponse response = RestAssured
.given() // Start forming the request
.basePath(basePath) // Set the base path
.baseUri(baseUrl) // Set the base URL
.contentType(ContentType.JSON) // Set the content type (JSON)
.body(body) // Set the request body
.when() // Finish forming the request and proceed to execution
.post() // Send a POST request
.then(); // Finish the request and proceed to checks

// Assert
response.assertThat().body(matchesJsonSchemaInClasspath(«bookingCreateResponseSchema.json»)); // Verify that the response matches the schema
}

/**
* Test to verify that creating a booking returns a status code of 200
*/
@Test
@DisplayName(«Create Booking has 200 status code»)
public void test2() {

// Arrange
String body = «»»
{
«firstname» : «Jim», // Customer’s first name
«lastname» : «Brown», // Customer’s last name
«totalprice» : 111, // Total price of the booking
«depositpaid» : true, // Flag indicating whether deposit is paid
«bookingdates» : { // Booking dates
«checkin» : «2018-01-01», // Check-in date
«checkout» : «2019-01-01» // Checkout date
},
«additionalneeds» : «Breakfast» // Customer’s additional needs
}
«»»;

// Act
ValidatableResponse response = RestAssured
.given() // Start forming the request
.basePath(basePath) // Set the base path
.baseUri(baseUrl) // Set the base URL
.contentType(ContentType.JSON) // Set the content type (JSON)
.body(body) // Set the request body
.when() // Finish forming the request and proceed to execution
.post() // Send a POST request
.then(); // Finish the request and proceed to checks

// Assert
response.assertThat().statusCode(200); // Verify that the response status code is 200
}

/**
* Test to verify that the response time for creating a booking is less than 3000ms
*/
@Test
@DisplayName(«Create Booking has response less than 3000ms»)
public void test3() {

// Arrange
String body = «»»
{
«firstname» : «Jim», // Customer’s first name
«lastname» : «Brown», // Customer’s last name
«totalprice» : 111, // Total price of the booking
«depositpaid» : true, // Flag indicating whether deposit is paid
«bookingdates» : { // Booking dates
«checkin» : «2018-01-01», // Check-in date
«checkout» : «2019-01-01» // Checkout date
},
«additionalneeds» : «Breakfast» // Customer’s additional needs
}
«»»;

// Act
ValidatableResponse response = RestAssured
.given() // Start forming the request
.basePath(basePath) // Set the base path
.baseUri(baseUrl) // Set the base URL
.contentType(ContentType.JSON) // Set the content type (JSON)
.body(body) // Set the request body
.when() // Finish forming the request and proceed to execution
.post() // Send a POST request
.then(); // Finish the request and proceed to checks

// Assert
response.assertThat().time(lessThan(3000L)); // Verify that the response time is less than 3000ms
}

/**
* Test to verify that the booking field has the correct value
*/
@Test
@DisplayName(«Create Booking field has value»)
public void test4() {

// Arrange
String body = «»»
{
«firstname» : «Jim», // Customer’s first name
«lastname» : «Brown», // Customer’s last name
«totalprice» : 111, // Total price of the booking
«depositpaid» : true, // Flag indicating whether deposit is paid
«bookingdates» : { // Booking dates
«checkin» : «2018-01-01», // Check-in date
«checkout» : «2019-01-01» // Checkout date
},
«additionalneeds» : «Breakfast» // Customer’s additional needs
}
«»»;

// Act
ValidatableResponse response = RestAssured
.given() // Start forming the request
.basePath(basePath) // Set the base path
.baseUri(baseUrl) // Set the base URL
.contentType(ContentType.JSON) // Set the content type (JSON)
.body(body) // Set the request body
.log().all() // Log the request
.when() // Finish forming the request and proceed to execution
.post() // Send a POST request
.then() // Finish the request and proceed to checks
.log().all(); // Log the response

// Assert
response.assertThat().body(«booking.firstname», equalTo(«Jim»)); // Verify that the «firstname» field has the value «Jim»
}
}

Складання тест-кейсів з редагування бронювання

Кроки:

Підготовка запиту з оновлення всіх полів бронювання:

    • firstname: «Jimmy»
    • lastname: «Brown»
    • totalprice: 222
    • depositpaid: true
    • bookingdates:
      • checkin: «2018-01-01»
      • checkout: «2019-01-02»
    • additionalneeds: «Breakfast»

Надсилання запиту на оновлення бронювання.

Перевірка: Переконайтеся, що відповідь відповідає схемі "bookingGetResponseSchema.json".

JSON  файл https://drive.google.com/file/d/1XqDr83yj2XJ5GElKm_QSSmmbpf3fgIr0/view?usp=sharing

Кроки:

Підготовка запиту з частковим оновленням полів бронювання:

    • firstname: «Jimmy»
    • lastname: «Brown»

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

Перевірка: Переконайтеся, що відповідь відповідає схемі "bookingGetResponseSchema.json".

JSON  файл https://drive.google.com/file/d/1XqDr83yj2XJ5GElKm_QSSmmbpf3fgIr0/view?usp=sharing

Написання автотесту з тест-кейсів з коментарями

package activities;

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import io.restassured.response.ValidatableResponse;
import org.junit.jupiter.api.*;

import static com.jayway.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath;


public class EditActivities {
private static String baseUrl = «https://restful-booker.herokuapp.com»;
private static String basePath = «/booking»;
private static String token;
private String id = «/» + 88;

// Obtaining the authentication token before running the tests
@BeforeAll
public static void getToken() {
String authPath = «/auth»;

// Authentication body
String body = «»»
{
«username» : «admin»,
«password» : «password123»
}
«»»;

// Sending a request to get the token
token = RestAssured // Assigning the token
.given() // Starting the REST Assured request
.baseUri(baseUrl) // Setting the base URI
.basePath(authPath) // Setting the base path
.contentType(ContentType.JSON) // Setting the content type as JSON
.body(body) // Setting the body of the request
.log().all() // Logging the request
.when() // Starting the HTTP request
.post() // Sending a POST request
.then() // Assertion part of the request
.log().all() // Logging the response
.extract().jsonPath().getJsonObject(«token»); // Extracting the token from the response body
}

@Test
@DisplayName(«Response in ‘Update All Booking fields’ method matches schema»)
public void test1() {
// Preparation
String body = «»»
{
«firstname» : «Jimmy»,
«lastname» : «Brown»,
«totalprice» : 222,
«depositpaid» : true,
«bookingdates» : {
«checkin» : «2018-01-01»,
«checkout» : «2019-01-02»
},
«additionalneeds» : «Breakfast»
}
«»»;

// Action: Updating all booking fields
ValidatableResponse response = RestAssured // Assigning the response
.given() // Starting the REST Assured request
.baseUri(baseUrl) // Setting the base URI
.basePath(basePath + id) // Setting the base path with the booking ID
.header(«Accept», «application/json») // Adding an accept header
.header(«Cookie», «token=» + token) // Adding the authentication token to the header
.contentType(ContentType.JSON) // Setting the content type as JSON
.body(body) // Setting the body of the request
.log().all() // Logging the request
.when() // Starting the HTTP request
.put() // Sending a PUT request
.then() // Assertion part of the request
.log().all(); // Logging the response

// Assertion: Verify that the response matches the schema
response.assertThat().body(matchesJsonSchemaInClasspath(«bookingGetResponseSchema.json»));
}

@Test
@DisplayName(«Response in ‘Partial Update Booking fields’ method matches schema»)
public void test2() {
// Preparation
String body = «»»
{
«firstname» : «Jimmy»,
«lastname» : «Brown»
}
«»»;

// Action: Partially updating booking fields
ValidatableResponse response = RestAssured // Assigning the response
.given() // Starting the REST Assured request
.baseUri(baseUrl) // Setting the base URI
.basePath(basePath + id) // Setting the base path with the booking ID
.header(«Accept», «application/json») // Adding an accept header
.header(«Cookie», «token=» + token) // Adding the authentication token to the header
.contentType(ContentType.JSON) // Setting the content type as JSON
.body(body) // Setting the body of the request
.log().all() // Logging the request
.when() // Starting the HTTP request
.patch() // Sending a PATCH request
.then() // Assertion part of the request
.log().all(); // Logging the response

// Assertion: Verify that the response matches the schema
response.assertThat().body(matchesJsonSchemaInClasspath(«bookingGetResponseSchema.json»));
}

@Test
@DisplayName(«Delete Booking»)
public void test3() {
// Action: Deleting a booking
ValidatableResponse response = RestAssured // Assigning the response
.given() // Starting the REST Assured request
.baseUri(baseUrl) // Setting the base URI
.basePath(basePath + id) // Setting the base path with the booking ID
.header(«Accept», «application/json») // Adding an accept header
.header(«Cookie», «token=» + token) // Adding the authentication token to the header
.contentType(ContentType.JSON) // Setting the content type as JSON
.log().all() // Logging the request
.when() // Starting the HTTP request
.delete() // Sending a DELETE request
.then() // Assertion part of the request
.log().all(); // Logging the response

// Assertion: Verify that the response status code is 201 (Created)
response.assertThat().statusCode(201);
}

// Performing cleanup after all tests
@AfterAll
public static void tearDown() {
System.gc();
}
}

Самостійна робота

  • Вивчити документацію
  • Дописати тест-кейси щодо створення та редагування бронювання
  • Дописати автотести

Розширені інструменти REST Assured

Фільтри (Filters)

REST Assured дозволяє використовувати фільтри для запитів та відповідей, що дає можливість маніпулювати даними до або після виконання запиту. Фільтри можуть бути використані для логування, аутентифікації, логування запитів та відповідей та інших завдань.

Приклад використання фільтрів:

public class CustomLogFilter implements Filter {
@Override
public Response filter(FilterableRequestSpecification requestSpec, FilterableResponseSpecification responseSpec, FilterContext ctx) {
System.out.println(«Request: » + requestSpec.getMethod() + » » + requestSpec.getURI());
Response response = ctx.next(requestSpec, responseSpec);
System.out.println(«Response: » + response.getStatusCode());
return response;
}
}

@Test
public void testWithCustomLogFilter() {
RestAssured
.filters(new CustomLogFilter())
.get(«/resource»)
.then()
.statusCode(200);
}

 

Сесії (Sessions)

REST Assured дозволяє працювати з сесіями, що особливо корисно у разі необхідності збереження стану між запитами, наприклад, авторизації.

Приклад використання сесій:

@Test
public void testWithSession() {
SessionFilter sessionFilter = new SessionFilter();


given().
filter(sessionFilter).
param(«username», «user»).
param(«password», «password»).
when().
post(«/login»).
then().
assertThat().
statusCode(200);


given().
filter(sessionFilter).
when().
get(«/user»).
then().
assertThat().
statusCode(200);
}

Логування (Logging)

REST Assured надає можливість логування запитів та відповідей, що полегшує налагодження та аналіз.

Приклад налаштування логування:
RestAssured
.given()
.log().all()
.when()
.get(«/resource»)
.then()
.log().all()
.statusCode(200);

Специфікація та конфігурація (Specification & Configuration)

REST Assured дозволяє створювати специфікації та конфігурації, що спрощує та стандартизує тести. Це робить ваш код більш чистим та модульним.

Приклад використання специфікацій та конфігурацій:

RequestSpecification requestSpec = new RequestSpecBuilder()
.setBaseUri(«http://api.example.com»)
.setContentType(ContentType.JSON)
.addHeader(«Authorization», «Bearer token»)
.build();

ResponseSpecification responseSpec = new ResponseSpecBuilder()
.expectStatusCode(200)
.expectContentType(ContentType.JSON)
.build();

@Test
public void testWithSpec() {
given().
spec(requestSpec).
when().
get(«/resource»).
then().
spec(responseSpec);
}

Серіалізація та десеріалізація (Serialization & Deserialization)

REST Assured надає можливість автоматичної серіалізації та десеріалізації об'єктів, що спрощує взаємодію з тілом запиту та відповіді.

Приклад серіалізації та десеріалізації:
MyObject myObject = new MyObject();
myObject.setName(«John»);
myObject.setAge(30);

given().
contentType(«application/json»).
body(myObject).
when().
post(«/resource»).
then().
statusCode(200);


MyObject responseObject = given().
contentType(«application/json»).
when().
get(«/resource»).
as(MyObject.class);

assertThat(responseObject.getName(), equalTo(«John»));
assertThat(responseObject.getAge(), equalTo(30));

Використання патернів проектування

REST Assured добре інтегрується з різними патернами проектування, такими як Page Object Pattern або Screenplay Pattern, що дозволяє спростити тестування та зробити його більш підтримуваним та модульним.

Приклад використання Page Object Pattern

public class APIPage {
private RequestSpecification requestSpec;

public APIPage(RequestSpecification requestSpec) {
this.requestSpec = requestSpec;
}

public Response getResource() {
return given()
.spec(requestSpec)
.when()
.get(«/resource»);
}
}

@Test
public void testWithPageObjectPattern() {
APIPage apiPage = new APIPage(requestSpec);
Response response = apiPage.getResource();

response.then().statusCode(200);
}

Інтеграція з Cucumber

Cucumber - це інструмент для автоматизованого тестування, який використовує мову Gherkin для написання тестових сценаріїв у форматі "Коли-Тогда-Еслі". REST Assured може бути легко інтегрований із Cucumber для написання більш зрозумілих тестів.

Feature: API Testing
Scenario: Verify resource endpoint
Given the base URI is «http://api.example.com»
When a GET request is sent to «/resource»
Then the response status code should be 200

І сам код

public class StepDefinitions {
private RequestSpecification requestSpec;
private Response response;

@Given(«the base URI is {string}»)
public void setBaseURI(String baseURI) {
requestSpec = new RequestSpecBuilder()
.setBaseUri(baseURI)
.build();
}

@When(«a GET request is sent to {string}»)
public void sendGetRequest(String endpoint) {
response = given()
.spec(requestSpec)
.when()
.get(endpoint);
}

@Then(«the response status code should be {int}»)
public void verifyStatusCode(int expectedStatusCode) {
response.then().statusCode(expectedStatusCode);
}
}

Місячний

ПРАКТИКУМ З REST ASSURED

Проходження повноцінного курсу REST Assured допоможе вам стати експертом у тестуванні REST API на мові Java і ефективно використовувати всі можливості цієї потужної бібліотеки для автоматизації тестування вашої програми.

Підтримка та питання

Якщо у вас виникли проблеми із запуском тестів або у вас є інші питання, не соромтеся звертатися до нас.

Через чат-бот

Надсилання завдання

Після завершення написання тестів, будь ласка, архівуйте ваш проект у форматі ZIP або RAR та надішліть нам для перевірки.