6 полезных советов по использованию REST-assured | OTUS

6 полезных советов по использованию REST-assured

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

1. Выносите end-point'ы в отдельное место

С одной стороны, это очевидно. Но увы, до сих пор нередко встречается код, имеющий захардкоженные end-point'ы в запросе. В целом же, лучше выносить end-point'ы в статические константы финального класса. Но тут есть нюанс — избегайте антипаттерна «константный интерфейс», т. к. это является плохой практикой. И помните, что REST-assured даёт возможность выносить параметры пути, к примеру:

public final class EndPoints {
    public static final String users = "/users/{id}";
...
}

given().pathParams("id", someId).get(EndPoints.users)...;

// или так

given().get(EndPoints.users, someId)....

Кроме того, если вы во многих запросах применяете одинаковый базовый путь, считается хорошей практикой выносить его в отдельную константу, передавая в basePath, как в примере ниже:

// имеем url приложения http://host:port/appname/rest/someEndpoints

private static final basePath = "/appname/rest/";

..

// можно задать базовый путь на глобальном уровне,
// и он будет использоваться ко всем запросам:
RestAssured.basePath = basePath;

// либо на уровне одного запроса:
given().basePath(basePath)...

// либо на уровне спецификации, но об этом поговорим позже

То же применимо как к хосту, так и к порту тестируемого программного приложения.

2. ContentType/Accept

Эти заголовки применяются почти во всех HTTP-запросах. Разработчики REST-assured прекрасно это понимают, поэтому они обеспечили возможность их установки посредством вызова специальных методов:

// вот то плохая практика написания:
given().header("content-type", "application/json").header("accept", "application/json")...;

// а вот эта хорошая:
given().contentType(ContentType.JSON).accept(ContentType.JSON)...;

Хорошей практикой станет установка данных заголовков в спецификации либо на глобальном уровне. Результат — повышение читабельности кода.

3. StatusCode и т. п.

Для выполнения проверки каждой составляющей HTTP-ответа, библиотека REST-assured предоставляет удобный синтаксис. Но на практике часто можно увидеть следующий код:

// это плохая практика написания:
Response response = given()...when().get(someEndpoint);
Assert.assertEquals(200, response.then().extract().statusCode());

//а это хорошая:
given()...when().get(someEndpoint).then().statusCode(200);

4. Используйте спецификации

Мы знаем, что дублировать код не есть хорошо. Для уменьшения дублирования нужно использовать спецификации. В REST-assured есть возможность создания спецификации и для запроса, и для ответа. В спецификацию запроса можно вынести всё, что можно продублировать в запросах.

RequestSpecification requestSpec = new RequestSpecBuilder()
    .setBaseUri("http://localhost")
    .setPort(8080)
    .setAccept(ContentType.JSON)
    .setContentType(ContentType.ANY)
...
    .log(LogDetail.ALL)
    .build();

// мы можем задать одну спецификацию для всех запросов:
RestAssured.requestSpecification = requestSpec;

// либо для отдельного:
given().spec(requestSpec)...when().get(someEndpoint);

Кроме того, в спецификацию ответа можно выносить все проверки, дублируемые от запроса к запросу.

ResponseSpecification responseSpec = new ResponseSpecBuilder()
    .expectStatusCode(200)
    .expectBody(containsString("success"))
    .build();

// мы можем задать одну спецификацию для всех ответов:
RestAssured.responseSpecification = responseSpec;

// либо для отдельного:
given()...when().get(someEndpoint).then().spec(responseSpec)...;

Также мы можем создавать несколько спецификаций для различных типов запросов/ответов и применять их в нужном случае.

5. Не надо писать собственные костыли для преобразования объектов

Не нужно преобразовывать свои POJO в JSON, используя Jackson ObjectMapper'а, а потом передавать полученную строку в тело запроса. Почему? Потому что с этой задачей отлично справляется библиотека REST-assured. Причём применяется всё тот же Jackson либо Gson с учётом того, что находится в classpath. А чтобы выполнить преобразование в XML, применяется JAXB. Что касается исходного формата, то он определяется автоматически по значению Content-Type.

given().contentType(ContentType.JSON).body(somePojo)
    .when().post(EndPoints.add)
    .then()
    .statusCode(201);

// то же самое действует и в обратную сторону:
SomePojo pojo = given().
    .when().get(EndPoints.get)
    .then().extract().body().as(SomePojo.class);

Вдобавок к вышесказанному, REST-assured хорошо справляется и с преобразованием HashMap в JSON и в обратном порядке.

6. Используйте всю силу Groovy

Так как сама библиотека написана на Groovy, она даёт возможность использовать к полученному JSON/XML-ответу разные методы из Groovy. Допустим:

// методы find, findAll используются к коллекции для поиска первого и всех вхождений, а метод collect — для  создания новой коллекции из найденных результатов. 

// переменная it создается неявно, указывая на текущий элемент коллекции
Map<String, ?> map = get(EndPoints.anyendpoint).path("rootelement.find { it.title =~ 'anythingRegExp'}");

// можно явно задать название переменной, указывающей на текущий элемент
Map<String, ?> map = get(EndPoints.anyendpoint).path("rootelement.findAll { element -> element.title.length() > 4 }");

// можно применять методы max, min, sum в целях суммирования всех значений коллекции и поиска максимального и минимально значений

String expensiveCar = get(EndPoints.cars).path("cars.find { it.title == 'Toyota Motor Corporation'}.models.max { it.averagePrice }.title");

Применение методов из Groovy сократит количество кода, написанного вами в целях поиска необходимого значения из ответа.

Источник

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
0 комментариев
Для комментирования необходимо авторизоваться
Популярное
Сегодня тут пусто