Существует несколько популярных способов описывать утверждения. Кроме вызова обычных методов, популярностью пользуются "матчеры", которые внешне выглядят как мини-язык для описания проверок. Мы уже начали с ними знакомиться на прошлом уроке.
Матчеры стали популярны в тестовых фреймворках после появления подхода BDD (Behaviour Driven Development, разработка через поведение). Технически, такой подход стремится сделать тесты похожими на словесное описание выполняемой задачи. Это даёт возможность использовать их как документацию людям, которые не умеют программировать (В идеале, на практике всё сложнее). Матчеры заменили собой обычные утверждения на функциях во многих языках:
int[] a = {1, 2, 3};
int[] b = {1, 2, 3};
// Проверка равенства по ссылке
// assert a == b;
assertThat(a).isSameAs(b); // false
// Проверка равенства по значению
// assert Arrays.equals(a, b);
assertThat(a).isEqualTo(b); // true
Любой матчер в AssertJ начинается с метода assertThat(data)
, в которую передаются данные на проверку. Затем assertThat
возвращает специальный объект, у которого уже можно вызывать различные матчеры для проверки. В AssertJ десятки матчеров для самых разнообразных ситуаций. Такое количество объясняется желанием выдавать максимально точный отчёт о том что произошло.
Предположим, что метод возвращает массив и мы хотим проверить его размер. Для этого можно воспользоваться матчером isEqualTo
:
int[] data = {1, 2, 3};
// take берет первые n элементов
// assert.equal(take(data, 2).length, 2)
assertThat(ArrayUtils.take(data, 2).length).isEqualTo(3);
Этот матчер прекрасно справится с задачей. Но в случае ошибки его вывод не слишком информативен:
Expecting:
<2>
to be equal to:
<3>
but was not.
Поэтому лучше взять специализированный матчер для проверки размера массива:
assertThat(take(data, 2)).hasSize(3);
Тогда вывод расскажет гораздо больше:
Expected size:<3> but was:<2> in:
<[1, 2]>
Благодаря тому, что в assertThat()
передаётся сам массив, а не его длина, у AssertJ появляется возможность выводить содержимое массива в случае ошибки. Это, опять же, упрощает отладку.
Ниже пример некоторых популярных матчеров, полезных в ежедневном тестировании:
char[] data = {'a', 'b', 'c'};
// проверка, что размеры объектов совпадают
assertThat(data).hasSameSizeAs(new int[] {1, 2, 3});
// проверка, что не null
assertThat(data).isNotNull();
// проверка, что выражение равно true
assertThat(true).isTrue();
// проверка, что объект находится в перечне
assertThat(1).isIn(1, 2, 3, 4);
// проверка, что число находится в отрезке [a, b]
assertThat(9).isBetween(9, 11);
// проверка, что число находится в интервале (a, b)
assertThat(10).isStrictlyBetween(9, 11);
Кроме того, практически все матчеры обладают как "позитивной" так и "негативной" версией:
assertThat(data).isNull();
assertThat(data).isNotNull();
assertThat(true).isTrue();
assertThat(false).isFalse();
assertThat(1).isIn(1, 2, 3, 4);
assertThat(1).isNotIn(2, 3, 4, 5);
Отдельно стоит выделить матчеры, которые работают с экземплярами классов. Для Java, как для ООП-языка, это особенно важно. В AssertJ есть матчеры, которые могут "обходить" переданные экземпляры классов и сравнивать их по отдельным полям.
// сравнение по ссылке
assertThat(obj1).isEqualTo(obj1);
// Каждое поле одного объекта сравнивается с соответствующим полем другого.
assertThat(obj1).isEqualToComparingFieldByField(obj2);
// далее рассмотрим только названия методов
// сравниваем, игнорируя поля, равные null
.isEqualToIgnoringNullFields()
// сравниваем только по указанному перечню полей
.isEqualToComparingOnlyGivenFields()
// все поля объекта равны null
.hasAllNullFieldsOrProperties()
Весь перечень подобных матчеров и примеров их использования можно найти в официальной документации AbstractObjectAssert.
Библиотека AssertJ позволяет собирать несколько тестов в один вызов:
public static void testMethod() {
var a = "Hello, world!";
assertThat(a) // утверждаем, что:
.startsWith("Hello") // строка начинается с подстроки "Hello"
.contains("llo, ") // содержит строку "llo, "
.endsWith("!"); // заканчивается строкой "!"
}
Такие тесты выполняются последовательно. Если провалится одно утверждение, то следующие за ним уже проверяться не будут. Это становится очевидным, если вспомнить, что при провале теста пробрасывается исключение.
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.