Использовали ли вы BDD-подход (Behavior-Driven Development) при написании тестов с REST Assured?

Ответ

Да, REST Assured отлично подходит для BDD-стиля благодаря своему fluent-интерфейсу, который напрямую соответствует структуре Given-When-Then. Его основные методы given(), when(), then() читаются как естественный язык.

Чистый BDD-стиль REST Assured (Java):

import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;

public class UserApiTest {

    @Test
    public void testGetUserById() {
        // Given - задаем начальные условия (предусловия)
        given()
            .baseUri("https://api.example.com")
            .header("Authorization", "Bearer " + authToken)
            .pathParam("userId", 42)

        // When - выполняем действие
        .when()
            .get("/users/{userId}")

        // Then - проверяем результат
        .then()
            .statusCode(200)
            .body("id", equalTo(42))
            .body("name", not(emptyString()))
            .body("email", containsString("@"));
    }

    @Test
    public void testCreateNewUser() {
        // Given
        String userJson = """
        {
            "name": "Анна Петрова",
            "email": "anna@example.com"
        }
        """;

        given()
            .contentType(ContentType.JSON)
            .body(userJson)

        // When
        .when()
            .post("/users")

        // Then
        .then()
            .statusCode(201)
            .header("Location", notNullValue())
            .body("id", greaterThan(0));
    }
}

Интеграция с полноценным BDD-фреймворком (Cucumber + REST Assured):

// Файл сценария: user_management.feature
Feature: Управление пользователями
  Scenario: Получение информации о пользователе
    Given у меня есть валидный токен доступа
    When я запрашиваю информацию о пользователе с ID 42
    Then я получаю ответ со статусом 200
    And в ответе есть поля id, name и email

// Step Definitions (Java)
public class UserSteps {
    private Response response;

    @Given("у меня есть валидный токен доступа")
    public void setupAuth() {
        RestAssured.requestSpecification = 
            new RequestSpecBuilder()
                .setBaseUri("https://api.example.com")
                .addHeader("Authorization", "Bearer " + getToken())
                .build();
    }

    @When("я запрашиваю информацию о пользователе с ID {int}")
    public void getUserById(int userId) {
        response = given()
                      .pathParam("id", userId)
                   .when()
                      .get("/users/{id}");
    }

    @Then("я получаю ответ со статусом {int}")
    public void verifyStatusCode(int expectedStatus) {
        response.then().statusCode(expectedStatus);
    }

    @And("в ответе есть поля id, name и email")
    public void verifyResponseFields() {
        response.then()
                .body("id", notNullValue())
                .body("name", not(emptyOrNullString()))
                .body("email", matchesPattern(".+@.+\..+"));
    }
}

Преимущества подхода:

  • Высокая читаемость: Тесты понятны не только разработчикам, но и бизнес-аналитикам и тестировщикам.
  • Естественная структура: Логичное разделение на подготовку, действие и проверку.
  • Гибкость: Можно использовать как самостоятельный BDD-стиль, так и в связке с Cucumber для работы с .feature-файлами.

Ограничения: Сам REST Assured не парсит .feature-файлы — для этого нужен отдельный фреймворк вроде Cucumber или JBehave.

Ответ 18+ 🔞

А, ну это же про REST Assured и его BDD-стиль, да? Ну, слушай, тут вообще красота, блядь, просто песня, а не фреймворк!

Вот смотри, сука, вся его фишка в том, что у него методы given(), when(), then() — это прям как будто ты на человеческом языке пишешь: «Допустим, вот это... Когда я сделаю вот это... Тогда должно быть вот это». Прям читаешь и понимаешь, что за хуйня тут тестируется, без всяких дебагов и поллитра не нужно!

Вот смотри, как это на Java выглядит, чистый BDD-стиль:

import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;

public class UserApiTest {

    @Test
    public void testGetUserById() {
        // Given - ну, типа, подготовительная хуйня, предпосылки
        given()
            .baseUri("https://api.example.com")
            .header("Authorization", "Bearer " + authToken)
            .pathParam("userId", 42)

        // When - а вот тут мы, сука, нажимаем на курок, делаем запрос!
        .when()
            .get("/users/{userId}")

        // Then - и тут начинается самая интересная часть: проверяем, не обосрался ли наш сервис
        .then()
            .statusCode(200)
            .body("id", equalTo(42))
            .body("name", not(emptyString()))
            .body("email", containsString("@"));
    }

    @Test
    public void testCreateNewUser() {
        // Given
        String userJson = """
        {
            "name": "Анна Петрова",
            "email": "anna@example.com"
        }
        """;

        given()
            .contentType(ContentType.JSON)
            .body(userJson)

        // When
        .when()
            .post("/users")

        // Then
        .then()
            .statusCode(201)
            .header("Location", notNullValue())
            .body("id", greaterThan(0));
    }
}

Видишь? Прям как инструкция, ёпта! «Допустим, у меня есть JSON. Когда я его пошлю на сервер. Тогда он должен ответить кодом 201 и выдать мне ID». Красота!

А если тебе, блядь, мало и хочется настоящего BDD с огоньком, то можно прикрутить Cucumber!

Тогда у тебя будут вот такие файлы-сценарии, которые даже менеджер, ебать его в сраку, поймёт:

# Файл сценария: user_management.feature
Feature: Управление пользователями
  Scenario: Получение информации о пользователе
    Given у меня есть валидный токен доступа
    When я запрашиваю информацию о пользователе с ID 42
    Then я получаю ответ со статусом 200
    And в ответе есть поля id, name и email

А потом пишешь на Java шаги, которые этот бред выполняют:

// Step Definitions (Java)
public class UserSteps {
    private Response response;

    @Given("у меня есть валидный токен доступа")
    public void setupAuth() {
        RestAssured.requestSpecification = 
            new RequestSpecBuilder()
                .setBaseUri("https://api.example.com")
                .addHeader("Authorization", "Bearer " + getToken())
                .build();
    }

    @When("я запрашиваю информацию о пользователе с ID {int}")
    public void getUserById(int userId) {
        response = given()
                      .pathParam("id", userId)
                   .when()
                      .get("/users/{id}");
    }

    @Then("я получаю ответ со статусом {int}")
    public void verifyStatusCode(int expectedStatus) {
        response.then().statusCode(expectedStatus);
    }

    @And("в ответе есть поля id, name и email")
    public void verifyResponseFields() {
        response.then()
                .body("id", notNullValue())
                .body("name", not(emptyOrNullString()))
                .body("email", matchesPattern(".+@.+\..+"));
    }
}

В чём, сука, соль-то?

  • Читаемость заебись: Теперь даже тот чувак, который только кофе делает, может заглянуть в .feature файл и сказать: «А, тут мы пользователя получаем!». Волшебство, ёпта!
  • Структура логичная: Всё по полочкам: подготовка, действие, проверка. Никакой каши в голове.
  • Гибкость, блядь: Хочешь — пиши тесты прямо в коде этим fluent-стилем. Хочешь — замути полноценный BDD с Cucumber и его файликами.

Но есть, блядь, и ложка дёгтя: Сам-то REST Assured не умеет читать эти .feature файлы. Это как купить крутой мотоцикл, но без ключа зажигания. Ключ — это отдельный фреймворк, типа того же Cucumber или JBehave. Без него — нихуя не взлетит.

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