REST Assured как инструмент тестирования API

Руслан Дзутцев
Effective Developers
8 min readNov 3, 2020

В современном мире существует множество инструментов для тестирования API, и сегодня речь пойдет об одном из представителей этого мира — инструменте Rest-Assured. На данный момент, это один из популярных инструментов для тестирования API, и различной информации о нем написано очень много, но мы хотели бы рассказать, чем именно он выделяется и как быстро начать писать на нем тесты.

Установка

Для начала определимся, что Rest-Assured это Java-библиотека для тестирования REST API. Подготовка и разбор документации может занять некоторое время, так как изначально рассматриваемый нами инструмент интуитивно не очень понятен, если “нырять в омут с головой” то можно потратить немало времени на начальном этапе.

Пожалуй, самый простой способ, с которым Rest-Assured работает и лучше всего визуализирует результаты — это работа в связке с Serenity (среда автоматизации тестирования с открытым исходным кодом). Для того чтобы начать писать тесты с помощью этого инструмента придется немного подготовиться. Для этого понадобится:

  1. Установить IntelliJ Idea Community (https://www.jetbrains.com/ru-ru/idea/download/#section=windows)
  2. Установить JDK8 (https://www.oracle.com/java/technologies/javase-downloads.html)
  3. Установить Maven (http://maven.apache.org/download.cgi)

Далее, нужно создать проект Maven с базовой структурой в Idea:

После этого можно начать добавлять необходимые зависимости Maven в файл pom.xml. Для того чтобы в последующем было удобнее писать и запускать тесты, добавим следующие зависимости включающие JUnit и Serenity:

Также нам понадобится подключить несколько плагинов:

В итоге pom.xml файл проекта должен иметь следующий вид:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>rest-assured-tests</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<serenity.version>1.5.8</serenity.version>
<serenity.maven.version>1.5.8</serenity.maven.version
<slf4j.version>1.6.1</slf4j.version
<maven.failsafe.plugin.version>2.18</maven.failsafe.plugin.version
<maven.compiler.plugin.version>3.2</maven.compiler.plugin.version
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>serenity-core</artifactId>
<version>${serenity.version}</version>
</dependency>

<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>serenity-junit</artifactId>
<version>${serenity.version}</version>
</dependency>
<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>serenity-rest-assured</artifactId
<version>${serenity.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- API, java.xml.bind module --> <dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId
<version>2.3.2</version>
</dependency>
<!-- Runtime, com.sun.xml.bind module --> <dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>serenity-core</artifactId>
<version>${serenity.version}</version>
</dependency>
</dependencies><build>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId
<version>${maven.failsafe.plugin.version}</version>
<configuration>
<includes>
<include>**/*.java</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>net.serenity-bdd.maven.plugins</groupId>
<artifactId>serenity-maven-plugin</artifactId
<version>${serenity.maven.version}</version>
<executions>
<execution>
<id>serenity-reports</id>
<phase>post-integration-test</phase>
<goals>
<goal>aggregate</goal>
</goals>
</execution>
</executions>
</project>

Все зависимости нужно заранее проверить на актуальность. Возможно, доступны обновленные версии.

С этого момента можно начинать писать свой первый тест.

Как видно, для начала работы с инструментом нужна небольшая, но все же требующая времени, подготовка. Такие инструменты для тестирования API как Postman дают вам все сразу и из коробки, буквально в одном приложении, что на начальном этапе дает легкость использования. С Rest-Assured же придется разбираться, хоть и недолго. В то же время инструмент дает то, чего нет у других инструментов — гибкость в кастомизации. Его можно использовать как отдельно, так и в связке с другими инструментами, например с вышеупомянутым Serenity для построения отчетов о тестировании.

Примеры

В качестве примера опишем несколько самых распространенных и используемых HTTP запросов — GET, POST, PUT и DELETE.

GET запрос

Для того чтобы написать и провести свой первый тест нам понадобится “Подопытный кролик”. Им может послужить Postman Echo, открытая документация от разработчиков другого инструмента тестирования API — Postman.

Давайте попробуем написать и выполнить для Rest-Assured следующий простой тест:

Для этого в проекте нужно создать новый Java class в папке src/test:

После чего написать сам GET запрос и тест. В случае с Rest-Assured тест будет иметь следующий вид:

package tests;
import io.restassured.RestAssured;
import org.junit.Test;
import static org.hamcrest.Matchers.is;
public class TestRestClass {
@Test
public void postmanFirstGetTest(){
RestAssured.
when().get("https://postman-echo.com/get?foo1=bar1&foo2=bar2").
then().assertThat().statusCode(200).
and().body("args.foo2", is("bar2"));
}
}

Разберем данный пример:

  1. Через when().get отправляется Get запрос на указанный URL.
  2. then().assertThat().statusCode(200) валидирует, что мы получили 200 код, и значит все прошло успешно.
  3. Ответ и последняя строчка проверяют что в body имеется аргумент foo2 со значением bar2.

Как видно из примера сам синтаксис написания тестов не очень сложен, что позволяет вам достаточно быстро написать тесты с помощью имеющейся у вас API документации.

POST запрос

Для написания этого запроса понадобится пример поинтереснее. Вместо Postman Echo будем использовать сервис для проверки запросов WebHook. Мы будем отправлять на этот ресурс запрос, после чего сможем увидеть, все ли отработало правильно. Для этого WebHook предоставляет нам уникальную ссылку для проверки наших запросов.

В случае Rest-Assured POST запрос будет выглядеть следующим образом:

@Testpublic void postRequestExampleTest() {
String someRandomString = String.format("%1$TH%1$TM%1$TS", new Date());
JSONObject requestBody = new JSONObject();
requestBody.put("FirstName", someRandomString);
requestBody.put("LastName", someRandomString);
requestBody.put("UserName", someRandomString);
requestBody.put("Password", someRandomString);
requestBody.put("Email", someRandomString + "@gmail.com");
RequestSpecification request = RestAssured.given();
request.header("Content-Type", "application/json");
request.body(requestBody.toJSONString());
Response response = request.post("https://webhook.site/a18a23cb-e9a0-4f03-a7fa-cdfcfa76ca98");
int statusCode = response.getStatusCode();
Assert.assertEquals(statusCode, 200);
System.out.println("The status code recieved: " + statusCode);

В данном запросе изначально задается произвольная переменная someRandomString, которая будет использоваться в дальнейшем для заполнения тела запроса уникальными значениями. Далее создается новый JSON объект (requestBody), с помощью которого, в дальнейшем, задаются отправляемые нами параметры, такие как FirstName, LastName, UserName, Password и Email. С помощью request.post отправляется запрос на тот URL, что был сформирован на WebHook. После того как запрос отработает, мы можем вернуться к WebHook и убедиться, что запрос был отправлен корректно с теми параметрами, которые были указаны.

PUT запрос

По своей сути PUT и POST достаточно схожи, различие заключается в том, что если POST запрос записывает на сервер новую информацию, то PUT обновляет уже имеющуюся, но если объекта не было на сервере, то он создаст новый. Следовательно, и реализация этого метода будет не сильно отличаться от предыдущей. Так же не следует путать с PATCH, он аналогичен PUT, но применяется только к фрагменту ресурса

Для примера нашего PUT запроса мы воспользуемся другим сервисом для проверки — https://dummy.restapiexample.com/.

Реализация PUT запроса для Rest-Assured будет выглядеть следующим образом:

@Test
public void UpdateRecordsWinthPut(){
int empid = 15410;
RestAssured.baseURI ="http://dummy.restapiexample.com/api/v1/";
RequestSpecification request = RestAssured.given();
JSONObject requestParams = new JSONObject();
requestParams.put("name", "TestDate");
requestParams.put("age", 23);
requestParams.put("salary", 12000);
request.body(requestParams.toJSONString());
Response response = request.put("/update/"+ empid);
int statusCode = response.getStatusCode();
System.out.println(response.asString());
Assert.assertEquals(statusCode, 200);
}

В данном примере можно увидеть, что переменная empid = 15410 — это то, что будет обновляться нашим запросом. После этого создается запрос, указывающий на конечную точку службы и создается JSON запрос, содержащий все поля, которые будут обновлены. С помощью request.put отправляется запрос, и проверяется, что ответ — 200. Все это, кроме самого первого шага, полностью перекликается с предыдущим запросом.

DELETE запрос

Исходя из прошлых примеров запрос Delete реализуется аналогично, лишь с небольшим изменением, вместо request.put следует использовать request.delete.

Общий вид запроса будет выглядеть в таком случае следующим образом:

@Testpublic void delete() {int empid = 15410;RestAssured.baseURI = "https://dummy.restapiexample.com/api/v1";
RequestSpecification request = RestAssured.given();
request.header("Content-Type", "application/json");
// Delete the request and check the response
Response response = request.delete("/delete/"+ empid);
int statusCode = response.getStatusCode();
System.out.println(response.asString());
Assert.assertEquals(statusCode, 200);
String jsonString =response.asString();
Assert.assertEquals(jsonString.contains("successfully! deleted Records"), true);
Assert.assertEquals(statusCode, 404);
String jsonString =response.asString();
Assert.assertEquals(jsonString.contains("Record to delete not found"), true);
}

При завершении выполнения запроса будет удалена запись, которую мы изменяли ранее (empid = 15410).

Для реализации тестов на Rest-assured хорошей практикой считается вынесение end-point’ов отдельно от тестов. Например, мы могли бы вынести наш baseURL с тестов, в отдельный класс:

public final class EndPoints {public static final String baseUrl = "https://dummy.restapiexample.com/api/v1";
...
}

И потом вызвать на уровне одного запроса посредством

given().basePath(basePath)

Визуализация результатов

И все-таки, выполнять тесты — это еще недостаточно, очень важна так же визуализация результатов, которую предлагает тот или иной инструмент.

Rest-Assured в своем изначальном состоянии не может похвастаться приятной глазу отчетностью. Единственное, что мы можем увидеть при запуске тестов — это результат выполнения теста:

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

Для построения наглядной отчетности мы уже прописали Serenity в наш pom.xml файл. Теперь же будет достаточно прописать @RunWith(SerenityRunner.class)перед тестами и в консоли запустить команду mvn clean verify. После выполнения команды в папке target вашего проекта создастся папка site с файлом index.html внутри, в котором будет лежать отчет примерно следующего формата:

В отчете будут отображены тесты (выполненные, успешные и провалившиеся), а также, один общий отчет, и отчет по каждому тесту в отдельности.

Целевая направленность

Если у вас уже есть UI автотесты, написанные например на Selenium + Java, то вам скорее всего хотелось бы создавать, хранить и выполнять все тесты одновременно, и при необходимости подключать API тесты. Для этого и существует такой инструмент как Rest-Assured. Мы можем объединять все автотесты в одном месте, запускать их на сервере, чтобы они проходили все время, а также, при сборке продукта. Это удобно, если тестов много, или приходится часто обращаться к регрессии. Иметь несколько инструментов на отдельные тесты, запускать их в разное время, смотреть разные отчеты становится неудобно, соразмерно росту числа ваших автотестов.

Исходя из всего, что было написано, можно сделать вывод, что, на начальном этапе Rest-Assured не самый легкий в освоении инструмент. Также он не очень подходит как отдельный инструмент для тестирования, или если нет большого регресса в API тестах. В то же время, инструмент будет очень удобен, если имеются UI автотесты и нужно автоматизировать API кейсы. Использование Rest-Assured в этой роли поможет сделать все как можно удобнее и легче, нежели использование отдельного инструмента. Также в связке с другими инструментами, такими как Serenity, он достаточно гибкий и имеет широкий потенциал для использования в автотестах.

Если вам или кому-то из ваших знакомых нужно разработать качественное мобильное приложение, веб-сервис, или помочь в решении бизнес-задач, смело обращайтесь к нам в Effective, мы готовы сотрудничать с вами в любом виде: как на проекте целиком, так и на аутстафф. Связаться с нами можно через почту contact@effective.band

--

--