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

Матчеры (Expectations) JS: Автоматическое тестирование

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

Матчеры стали популярны в тестовых фреймворках после появления подхода BDD (Behaviour Driven Development, разработка через поведение). Технически, такой подход стремится сделать тесты похожими на словесное описание выполняемой задачи. Это даёт возможность использовать их как документацию людям, которые не умеют программировать (В идеале, на практике всё сложнее). Матчеры заменили собой обычные утверждения на функциях во многих языках:

// Проверка равенства по ссылке
// assert.equal([1, 2], [1, 2])
expect([1, 2]).toBe([1, 2]); // false

// Проверка равенства по значению
// assert.deepEqual([1, 2], [1, 2])
expect([1, 2]).toEqual([1, 2]); // true

Любой матчер в Jest начинается с функции expect(data), в которую передаются данные на проверку. Затем expect возвращает специальный объект, у которого уже можно вызывать различные матчеры для проверки. В Jest десятки матчеров для самых разнообразных ситуаций. Такое количество объясняется желанием выдавать максимально точный отчёт о том, что произошло.

Предположим, что функция возвращает массив и мы хотим проверить его размер. Для этого можно воспользоваться матчером toBe:

const data = [1, 2, 3];
// take берет первые n элементов
// assert.equal(take(data, 2).length, 2)
expect(take(data, 1).length).toBe(2);

Этот матчер прекрасно справится с задачей. Но в случае ошибки его вывод не слишком информативен:

expect(received).toBe(expected) // Object.is equality

Expected: 2
Received: 1

Поэтому лучше взять специализированный матчер для проверки размера массива:

expect(take(data, 1)).toHaveLength(2);

Тогда вывод расскажет гораздо больше:

expect(received).toHaveLength(expected)

Expected length: 2
Received length: 1
Received array:  [1]

Благодаря тому, что в expect передаётся сам массив, а не его длина, у Jest появляется возможность выводить содержимое массива в случае ошибки. Это, опять же, упрощает отладку.

Ниже пример некоторых популярных матчеров, полезных в ежедневном тестировании:

expect(null).toBeNull();

// Проверяет значение на truthy (любое значение, которое приводится к true)
expect(true).toBeTruthy();
// Точное сравнение с true
expect(true).toBe(true);

expect(undefined).toBeUndefined();

// Проверка, что массив содержит элемент
expect([1, 2, 3]).toContain(2);

// Проверка, что строка содержит подстроку
expect('hello, world').toMatch('hello');

// Проверяет, что в объекте есть свойство с определённым значением
expect({ key: 'value' }).toHaveProperty('key', 'value');

Кроме того, к любому матчеру можно применить модификатор not, который инвертирует поведение матчера:

expect(null).not.toBeNull(); // not null
expect(undefined).not.toBeUndefined(); // not undefined
expect([1, 2, 3]).not.toContain(2); // not contain 2
expect('hello, world').not.toMatch('hello'); // not match hello

https://repl.it/@hexlet/js-testing-matchers-expect#index.test.js

Особняком стоит матчер toMatchObject. Он используется, когда нас в тестах интересует не весь объект, а только какая-то его часть:

const user = {
  firstName: 'tolya',
  lastName: 'petrov',
  age: '33',
};

// Тест пройдёт успешно, так как проверяется только firstName
expect(user).toMatchObject({ firstName: 'tolya' });

Это далеко не все матчеры, которые есть в Jest. Более того, Jest достаточно гибкий и может расширяться собственными матчерами. На Гитхабе можно найти библиотеки с матчерами для разных ситуаций.

В целом, вам придётся постоянно заглядывать в документацию, чтобы вспомнить, что там есть. Иначе всё может свестись к использованию toEqual. Пожалуй, это основной недостаток использования матчеров — необходимость помнить про них и правильно применять.


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

  1. Матчеры Jest

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

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

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

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

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

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

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

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

Для полного доступа к курсу нужна профессиональная подписка

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

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

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

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

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

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

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

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

Иконка программы Фронтенд-разработчик
Профессия
Разработка фронтенд-компонентов веб-приложений
22 сентября 8 месяцев
Иконка программы Node.js-разработчик
Профессия
Разработка бэкенд-компонентов веб-приложений
22 сентября 8 месяцев

Есть вопрос или хотите участвовать в обсуждении?

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

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