automated tests using Rest-assured
This commit is contained in:
41
.gitignore
vendored
Normal file
41
.gitignore
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea/modules.xml
|
||||||
|
.idea/jarRepositories.xml
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/libraries/
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
||||||
|
/.idea/
|
||||||
|
/.mvn/
|
||||||
|
/.gitignore
|
||||||
96
pom.xml
Normal file
96
pom.xml
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<!-- Основная информация о проекте -->
|
||||||
|
<groupId>ru.otus</groupId>
|
||||||
|
<artifactId>petstore</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<name>petstore</name>
|
||||||
|
|
||||||
|
<!-- Глобальные свойства проекта -->
|
||||||
|
<properties>
|
||||||
|
<!-- Используем Java 24 -->
|
||||||
|
<maven.compiler.source>24</maven.compiler.source>
|
||||||
|
<maven.compiler.target>24</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<!-- Версии зависимостей -->
|
||||||
|
<restassured.version>4.5.1</restassured.version>
|
||||||
|
<junit.jupiter.version>5.9.1</junit.jupiter.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<!-- Зависимости проекта -->
|
||||||
|
<dependencies>
|
||||||
|
<!-- Rest-assured для работы с REST API с исключением транзитивой зависимости commons-codec -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.rest-assured</groupId>
|
||||||
|
<artifactId>rest-assured</artifactId>
|
||||||
|
<version>${restassured.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>commons-codec</groupId>
|
||||||
|
<artifactId>commons-codec</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Явное подключение обновлённой, безопасной версии commons-codec -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-codec</groupId>
|
||||||
|
<artifactId>commons-codec</artifactId>
|
||||||
|
<version>1.15</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- JSON-парсинг через Rest-assured -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.rest-assured</groupId>
|
||||||
|
<artifactId>json-path</artifactId>
|
||||||
|
<version>${restassured.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- JUnit Jupiter API для написания автотестов (включает ExtensionContext и TestWatcher) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
|
<version>${junit.jupiter.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- JUnit Jupiter Engine для выполнения тестов -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
<version>${junit.jupiter.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<!-- Конфигурация сборки проекта -->
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<!-- Maven Compiler Plugin для компиляции проекта с поддержкой Java 24 -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.11.0</version>
|
||||||
|
<configuration>
|
||||||
|
<source>${maven.compiler.source}</source>
|
||||||
|
<target>${maven.compiler.target}</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!-- Maven Surefire Plugin для запуска тестов -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.22.2</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
170
src/test/java/ru/otus/petstore/PetStoreTests.java
Normal file
170
src/test/java/ru/otus/petstore/PetStoreTests.java
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
package ru.otus.petstore;
|
||||||
|
|
||||||
|
import io.restassured.RestAssured;
|
||||||
|
import io.restassured.http.ContentType;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Order;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
|
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.junit.jupiter.api.extension.TestWatcher;
|
||||||
|
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static io.restassured.RestAssured.given;
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
|
@ExtendWith(PetStoreTests.TestResultLogger.class)
|
||||||
|
@TestMethodOrder(OrderAnnotation.class)
|
||||||
|
public class PetStoreTests {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Выполняется один раз перед запуском всех тестов.
|
||||||
|
* Устанавливаем базовый URI для запросов к Swagger Petstore API.
|
||||||
|
*/
|
||||||
|
@BeforeAll
|
||||||
|
public static void setup() {
|
||||||
|
RestAssured.baseURI = "https://petstore.swagger.io/v2";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Тест 1: GET /pet/findByStatus (status = available).
|
||||||
|
* Ожидается статус 200 и все объекты в ответе должны иметь поле "status" равное "available".
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Order(1)
|
||||||
|
@DisplayName("1. Test: Find pets by 'available' status")
|
||||||
|
public void testFindPetsByAvailableStatus() {
|
||||||
|
given()
|
||||||
|
.queryParam("status", "available")
|
||||||
|
.when()
|
||||||
|
.get("/pet/findByStatus")
|
||||||
|
.then()
|
||||||
|
.statusCode(200)
|
||||||
|
.body("status", everyItem(equalTo("available")));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Тест 2: GET /pet/findByStatus с несуществующим статусом "invalidStatus".
|
||||||
|
* Ожидается статус 200 и пустой массив в ответе.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Order(2)
|
||||||
|
@DisplayName("2. Test: Find pets by invalid status")
|
||||||
|
public void testFindPetsByInvalidStatus() {
|
||||||
|
given()
|
||||||
|
.queryParam("status", "invalidStatus")
|
||||||
|
.when()
|
||||||
|
.get("/pet/findByStatus")
|
||||||
|
.then()
|
||||||
|
.statusCode(200)
|
||||||
|
.body("", hasSize(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Тест 3: POST /pet для создания питомца с валидными данными.
|
||||||
|
* Ожидается статус 200 и возвращаемое поле "name" совпадает с переданным.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Order(3)
|
||||||
|
@DisplayName("3. Test: Create pet successfully")
|
||||||
|
public void testCreatePetSuccess() {
|
||||||
|
int petId = (int) (System.currentTimeMillis() % Integer.MAX_VALUE);
|
||||||
|
String petName = "Rex";
|
||||||
|
String requestBody = "{\n" +
|
||||||
|
" \"id\": " + petId + ",\n" +
|
||||||
|
" \"category\": { \"id\": 1, \"name\": \"Dogs\" },\n" +
|
||||||
|
" \"name\": \"" + petName + "\",\n" +
|
||||||
|
" \"photoUrls\": [ \"http://example.com/photo.jpg\" ],\n" +
|
||||||
|
" \"tags\": [ { \"id\": 0, \"name\": \"string\" } ],\n" +
|
||||||
|
" \"status\": \"available\"\n" +
|
||||||
|
"}";
|
||||||
|
given()
|
||||||
|
.contentType(ContentType.JSON)
|
||||||
|
.body(requestBody)
|
||||||
|
.when()
|
||||||
|
.post("/pet")
|
||||||
|
.then()
|
||||||
|
.statusCode(200)
|
||||||
|
.body("name", equalTo(petName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Тест 4: POST /pet для создания питомца с невалидными данными (без поля "name").
|
||||||
|
* Ожидается, что API вернёт ошибку (400 или 405).
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Order(4)
|
||||||
|
@DisplayName("4. Test: Create pet missing 'name' field")
|
||||||
|
public void testCreatePetMissingName() {
|
||||||
|
int petId = (int) (System.currentTimeMillis() % Integer.MAX_VALUE);
|
||||||
|
String requestBody = "{\n" +
|
||||||
|
" \"id\": " + petId + ",\n" +
|
||||||
|
" \"category\": { \"id\": 1, \"name\": \"Dogs\" },\n" +
|
||||||
|
" \"photoUrls\": [ \"http://example.com/photo.jpg\" ],\n" +
|
||||||
|
" \"tags\": [ { \"id\": 0, \"name\": \"string\" } ],\n" +
|
||||||
|
" \"status\": \"available\"\n" +
|
||||||
|
"}";
|
||||||
|
given()
|
||||||
|
.contentType(ContentType.JSON)
|
||||||
|
.body(requestBody)
|
||||||
|
.when()
|
||||||
|
.post("/pet")
|
||||||
|
.then()
|
||||||
|
.statusCode(anyOf(is(400), is(405)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Тест 5: POST /pet с некорректным JSON (отсутствует закрывающая фигурная скобка).
|
||||||
|
* Ожидается, что API вернёт ошибку (400 или 405).
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Order(5)
|
||||||
|
@DisplayName("5. Test: Create pet with invalid JSON")
|
||||||
|
public void testCreatePetInvalidJson() {
|
||||||
|
String invalidJson = "{\n" +
|
||||||
|
" \"id\": 123456,\n" +
|
||||||
|
" \"name\": \"Invalid Pet\",\n" +
|
||||||
|
" \"category\": { \"id\": 1, \"name\": \"Dogs\" },\n" +
|
||||||
|
" \"photoUrls\": [ \"http://example.com/photo.jpg\" ],\n" +
|
||||||
|
" \"tags\": [ { \"id\": 0, \"name\": \"string\" } ],\n" +
|
||||||
|
" \"status\": \"available\"\n"; // отсутствует закрывающая фигурная скобка
|
||||||
|
given()
|
||||||
|
.contentType(ContentType.JSON)
|
||||||
|
.body(invalidJson)
|
||||||
|
.when()
|
||||||
|
.post("/pet")
|
||||||
|
.then()
|
||||||
|
.statusCode(anyOf(is(400), is(405)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Реализация TestWatcher для логирования результата каждого теста.
|
||||||
|
* Выводит сообщения: если тест пройден – "Test Passed", иначе "Test Failed", "Test Aborted" или "Test Disabled".
|
||||||
|
*/
|
||||||
|
public static class TestResultLogger implements TestWatcher {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testSuccessful(ExtensionContext context) {
|
||||||
|
System.out.println(context.getDisplayName() + " - Passed");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testFailed(ExtensionContext context, Throwable cause) {
|
||||||
|
System.out.println(context.getDisplayName() + " - Failed: " + cause.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testAborted(ExtensionContext context, Throwable cause) {
|
||||||
|
System.out.println(context.getDisplayName() + " - Aborted");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testDisabled(ExtensionContext context, Optional<String> reason) {
|
||||||
|
System.out.println(context.getDisplayName() + " - Disabled: " + reason.orElse("No reason provided"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user