Як дадаць агурочны пласт уверх надзейна правераных тэстаў API

У гэтым паведамленні прыводзіцца пакрокавае кіраўніцтва па тым, як дадаць пласт агурка паверх тэстаў API, напісаных у REST-запэўніванні.

DSL, які гарантуе REST, ужо забяспечвае напісанне тэстаў у стылі BDD у фармаце 'Дадзена-калі-потым', але ўсё роўна пахавана ў кодзе. Іншымі словамі, калі вы хочаце паглядзець, якія сцэнарыі ахоплены, вам усё роўна прыйдзецца паглыбіцца ў тэсты api і прачытаць код. Файлаў функцый няма.

Мэтай гэтага паведамлення з'яўляецца перапрацоўка існуючых API-тэстаў, якія забяспечваюць REST, шляхам дадання файлаў агуркоў і функцый, каб сцэнарыі маглі быць прачытаны больш выразна без неабходнасці разглядаць асноўны код.




АДПАЧАКАНЫЯ тэсты API

У гэтым прыкладзе мы напішам код для праверкі API стварэння карыстальнікаў.

Па-першае, у нас ёсць аўтаномны REST-assured і 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() метад усталёўвае перадумову. Тэставы метад вырабляе дзеянні (адпраўка запыту), а затым сцвярджае на кодзе адказу і карыснай нагрузцы адказу.

Далей мы разгледзім, як пакласці агурочны пласт па-над вышэйапісанага тэсту АПІ, які забяспечвае REST.




Агурок і REST-гарантаваныя тэсты API

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

Выкарыстоўваючы 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. Паступаючы такім чынам, мы можам запісваць свае сцэнарыі ў файлы функцый, якія становяцца больш чытэльнымі для нетэхнічных людзей.