Как добавить слой огурца поверх тестов API с поддержкой REST

В этом посте представлено пошаговое руководство о том, как добавить слой огурца поверх тестов API, написанных на REST-гарантированном.

DSL с гарантированным REST уже обеспечивает написание тестов в стиле BDD в формате Given-When-Then, но он все еще скрыт в коде. Другими словами, если вы хотите увидеть, какие сценарии охватываются, вам все равно придется покопаться в тестах api и прочитать код. Нет файлов функций.

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




Тесты API с гарантией REST

В этом примере мы напишем код для тестирования API создания пользователей.

Во-первых, у нас есть автономный тест REST и JUnit Test, который находится в:


src/test/java/io.devqa/scenarios



import io.restassured.RestAssured; import io.restassured.http.ContentType; import io.restassured.response.Response; import org.junit.jupiter.api.*; import static io.restassured.RestAssured.given; public class UserTests {
private static String path;
private static String validRequest = '{ ' +

' 'username': 'test-api-user', ' +

' 'email': 'test-api-user@email.com', ' +

' 'password': 'Passw0rd123!', ' +

' 'name': 'Test Api-User' }';
@BeforeAll
public static void setConfig() {
RestAssured.baseURI = 'https://localhost:8080';
path = '/users';
}
@Test
public void shouldBeAbleToCreateNewUser() {
Response createUser = given()


.auth()


.preemptive()


.basic('MY_USERNAME', 'MY_PASSWORD')


.header('Accept', ContentType.JSON.getAcceptHeader())


.contentType(ContentType.JSON)


.body(validRequest)


.post(path)


.then().extract().response();
Assertions.assertEquals(201, createUser.getStatusCode());

String username = createUser.jsonPath().get('username');
String email = createUser.jsonPath().get('email');
String name = createUser.jsonPath().get('name');
String id = createUser.jsonPath().get('id');

Assertions.assertEquals('test-api-user', username);
Assertions.assertEquals('test-api-user@email.com', email);
Assertions.assertEquals('Test Api-User', name);
Assertions.assertNotNull(id);
} }

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

setConfig() метод устанавливает предварительное условие. Метод тестирования выполняет действия (отправляет запрос), а затем утверждает код ответа и полезную нагрузку ответа.

Далее мы рассмотрим, как разместить слой огурца поверх указанного выше теста API с гарантированным REST.




Тесты API на основе огурцов и REST

Первое, что нам нужно сделать, это добавить в наш проект зависимость огурца.

Используя Gradle в нашем build.gradle файл, мы помещаем их в dependencies:

dependencies {
testCompile 'io.cucumber:cucumber-java:6.2.2'
testCompile 'io.cucumber:cucumber-junit:6.2.2'
testCompile 'io.rest-assured:rest-assured:3.3.0'
testCompile 'com.jayway.jsonpath:json-path:2.4.0' }

И эти под configuration в build.gradle файл:

configurations {
cucumberRuntime {
extendsFrom testImplementation
} }

Также нам нужно создать задачу в build.gradle файл для запуска файлов функций огурца, которые содержат сценарии:


task cucumber() {
dependsOn assemble, compileTestJava
doLast {
mkdir 'build/test-results/'
javaexec {

main = 'io.cucumber.core.cli.Main'

classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output

args = ['--plugin', 'pretty', '--plugin', 'html:build/test-results/functional.html', '--plugin', 'junit:build/test-results/functional.xml','--tags', '@functional', '--glue', 'scenarios', 'src/test/resources']
}
} }

Структура проекта для огурца

Нам также необходимо изменить структуру нашего проекта, чтобы учесть изменения для огурца.

Файлы функций будут сохранены в:

src/test/resources/scenarios

Определения шагов будут сохранены в


src/test/java/scenarios

Затем мы создадим файл функций с именем UserScenarios.feature и поместите его в src/test/resources/scenarios папка.

Файл функций будет выглядеть так:

@functional Feature: User Scenarios Scenario: I should be able to create a new user
Given the users endpoint exists
When I send a valid create user payload
Then response status code should be 201
And create user response should be valid

Теперь нам нужно разобрать наш тест JUnit с гарантированным REST, чтобы написать определения шагов, которые можно приклеить к операторам в нашем файле функций.


import io.cucumber.java.en.And; import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import io.cucumber.java.en.When; import io.restassured.RestAssured; import io.restassured.http.ContentType; import io.restassured.response.Response; import org.junit.jupiter.api.Assertions; import static io.restassured.RestAssured.given; public class UserScenarios {
private String path;
private Response response;
private String validRequest = '{ ' +

' 'username': 'test-api-user', ' +

' 'email': 'test-api-user@email.com', ' +

' 'password': 'Passw0rd123!', ' +

' 'name': 'Test Api-User' }';
@Given('the users endpoint exists')
public void preReq() {
RestAssured.baseURI = 'https://localhost:8080';
path = '/users';
}
@When('I send a valid create user payload')
public void createUser() {
response = given()


.auth()


.preemptive()


.basic('MY_USERNAME', 'MY_PASSWORD')


.header('Accept', ContentType.JSON.getAcceptHeader())


.contentType(ContentType.JSON)


.body(validRequest)


.post(path)


.then().extract().response();
}
@Then('response status code should be {int}')
public void checkResponseStatusCode(int code) {
Assertions.assertEquals(code, response.getStatusCode());
}
@And('create user response should be valid')
public void verifyResponse() {
String username = response.jsonPath().get('username');
String email = response.jsonPath().get('email');
String name = response.jsonPath().get('name');
String id = response.jsonPath().get('id');

Assertions.assertEquals('test-api-user', username);
Assertions.assertEquals('test-api-user@email.com', email);
Assertions.assertEquals('Test Api-User', name);
Assertions.assertNotNull(id);
} }

Как видно из приведенных выше определений шагов, для каждой строки сценария в файле функций у нас есть соответствующее определение шага.

Метод с Given аннотация устанавливает предварительные условия. Метод с When аннотация выполняет действие отправки запроса и, наконец, метода с Then аннотация выполняет утверждения в ответе.

Для выполнения вышеизложенного все, что нам нужно сделать, это выполнить команду ./gradle cucumber в терминале из корня проекта.

После запуска тестов результаты сохраняются в build/test-results/functional.html.



Заключение

В этом посте мы рассмотрели пошаговое руководство о том, как добавить слой огурца поверх тестов API с гарантированным REST. Поступая так, мы можем записывать наши сценарии в файлы функций, которые станут более удобочитаемыми для нетехнических специалистов.