175 lines
6.9 KiB
Java
175 lines
6.9 KiB
Java
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). Почему-то сервис отдает ответ 200
|
||
* я решил оставить данный тест. Показать что вся цепочка тестов не останавливается и
|
||
* продолжает работать дальше
|
||
*/
|
||
@Test
|
||
@Order(4)
|
||
@DisplayName("4. Test: Fail to create pet without '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 = """
|
||
{
|
||
"id": 123456,
|
||
"name": "Invalid Pet",
|
||
"category": { "id": 1, "name": "Dogs" },
|
||
"photoUrls": [ "http://example.com/photo.jpg" ],
|
||
"tags": [ { "id": 0, "name": "string" } ],
|
||
"status": "available"
|
||
"""; // отсутствует закрывающая фигурная скобка
|
||
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"));
|
||
}
|
||
}
|
||
}
|