Как писать проверки быстро
Сегодня продолжу разговор о том, как писать автотесты быстро. Мы уже разобрались, как очень быстро и эффективно конвертировать REST ответы в Java объекты.
Пришло время научиться так же быстро проверять данные, которые хранятся в этих объектах. Не так давно я делился подборкой полезных библиотек, которые значительно упрощают процесс написания проверок в тестах.
Еще пару лет назад для написания ассертов я активно использовал библиотеку Hamcrest Matchers. Классная библиотека, которая отлично справляется со своими задачами, пока дело не доходит до создания матчеров для своих кастомных классов.
Вот, к примеру, у нас есть класс:
class User{
String name;
String password;
List<String> phoneNumbers;
}
Используя Hamcrest, мы можем написать:
public void testUserInfo(){
User user = when().get("/users").then().extract().response().as(User.class);
assertThat(user.name, equalTo("name"))
assertThat(user.password, equalTo("test"))
assertThat(user.phoneNumbers, hasItem("+1(234)567"))
}
Достаточно неплохо, если вам нужно написать такой код в одном тесте и для одного объекта. Hamcrest позволяет писать кастомные матчеры. Но писать матчеры руками - занятие унылое. Поверьте мне, я пробовал. Польза в этом одна: вы начинаете понимать, как библиотека работает внутри. Благо, в Github можно найти утилиту, которая позволяет генерировать матчеры.
Работает она достаточно просто: берем свой класс, ставим над нужными полями аннотацию @GenerateMatcher
, запускаем генерилку
и на выходе получаем готовые матчеры.
Используя эту супервозможность, мы можем написать такой код:
public void testUserInfo(){
User user = when().get("/users").then().extract().response().as(User.class);
assertThat(user, hasName("name"))
assertThat(user, hasPassword("test"))
assertThat(user, hasPhoneNumberItem("+1(234)567"))
}
Хорошо. Но идти и руками ставить аннотации - скукотища! Да и генерилка работает только в связке с Maven. Можно сделать гораздо круче, но для этого нужно сменить знакомый нам Hamcrest на Assertj.
Отмечу, что синтаксис assertj отличается от того, который мы писали с Hamcrest. Поэтому при переходе вам нужно будет переписать много кода.
Assertj тоже позволяет генерировать матчеры для Java классов. Радует, что для этого есть плагины как для Maven, так и для Gradle. В документации достаточно хорошо описаны способы подключения плагинов.
С помощью assertj assertion generator мы можем генерировать матчеры для любого класса, просто указав путь к пакету, без какой-либо надобности ставить дополнительные аннотации. Для меня это архиважно, так как не всегда есть возможность менять код доменных объектов.
Давайте посмотрим, как изменится код тестов при использовании assertj:
public void testUserInfo(){
User user = when().get("/users").then().extract().response().as(User.class);
UserAssert.assertThat(user)
.hasName("user")
.hasPassword("test")
.hasPhoneNumberItem("+1(234)567");
}
Чем такой подход круче?
Вы генерируете 80% кода автоматически. Остается написать вызов нужных методов RestAssured и соответствующих проверок. В случае, если ваша доменная модель меняется - скажем, какое-то поле удаляется или меняет тип - все, что нужно будет сделать, - это вызвать ./gradlew generateJsonSchema2Pojo assertjGen и код автоматически обновится. Вам останется немного подправить тесты. Я такой подход успешно использую на своем текущем проекте - работает просто шикарно. Рекомендую попробовать - вам понравится.