Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Матчеры Java: Автоматическое тестирование

Существует несколько популярных способов описывать утверждения. Кроме вызова обычных методов, популярностью пользуются "матчеры", которые внешне выглядят как мини-язык для описания проверок. Мы уже начали с ними знакомиться на прошлом уроке.

Матчеры стали популярны в тестовых фреймворках после появления подхода 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("!");      // заканчивается строкой "!"
    }

Такие тесты выполняются последовательно. Если провалится одно утверждение, то следующие за ним уже проверяться не будут. Это становится очевидным, если вспомнить, что при провале теста пробрасывается исключение.


Дополнительные материалы

  1. Документация AssertJ
  2. Javadoc для AssertJ Core

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.

Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Java-разработчик
Профессия
Разработка приложений на языке Java
25 мая 10 месяцев

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»