Когда тестов и файлов с тестами становится много, возникают новые вопросы. Как группировать тесты? Как запустить на выполнение все тесты из одной директории? Если их очень много и они долгие, можно ли запустить их параллельно?
Для решения этих вопросов используют специальные тестовые фреймворки. Они помогают организовать структуру тестов и дают много полезного, например, удобный вывод. С большинством из этих возможностей мы познакомимся далее по курсу. В JavaScript-мире наиболее популярен фреймворк Jest, разрабатываемый компанией Facebook. К слову, с помощью него мы тестируем все практики на Хекслете.
Ниже находится инструкция, в которой мы создадим с нуля npm-проект и добавим в него тесты.
Настройка и запуск
Создайте где-нибудь на вашем компьютере директорию с названием hexlet-jest. Зайдите в неё и выполните команду:
npm init
Ответьте на все вопросы запущенного скрипта инициализации проекта. Убедитесь, что в корне проекта появился файл package.json.
Теперь добавим немного исходного кода. Создайте файл src/index.js с таким содержимым:
// Эта функция переворачивает переданную строку
export default str => str.split('').reverse().join('');
Jest — обычный npm-пакет, который локально подключается в разрабатываемый проект. Jest нужен только во время разработки, поэтому лучше установить его в секцию devDependencies:
# В директории с проектом
npm i --save-dev jest
Чтобы Jest корректно работал с системой модулей, добавьте в package.json следующую опцию:
"type": "module"
Jest ожидает, что тесты находятся в директории __tests__, которую обычно располагают в корне проекта. Внутри этого каталога можно создавать любую структуру, Jest найдёт все тесты, которые там лежат. Именование файлов с тестами должно быть таким: <name>.test.js
. Где <name>
, как правило, соответствует имени модуля, который тестируется.
Напишем наш первый тест. Создайте файл __tests__/index.test.js со следующим содержимым:
import reverse from '../src/index.js';
test('reverse', () => {
expect(reverse('hello')).toEqual('olleh');
expect(reverse('')).toEqual('');
});
Далее мы разберём структуру этого файла, а пока попробуем запустить тест на выполнение:
# Jest поддерживает ECMAScript модули в экспериментальном режиме
# Чтобы активировать поддержку модулей в тестах,
# нужно запускать тесты с переменной окружения NODE_OPTIONS
NODE_OPTIONS=--experimental-vm-modules npx jest
PASS __tests__/index.test.js
✓ reverse (11ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.166s
Ran all test suites.
https://replit.com/@hexlet/js-testing-jest-1#__test__/index.test.js
Ура! Тесты прошли успешно.
Структура
Давайте ещё раз посмотрим на файл с тестом:
import reverse from '../src/index.js';
test('reverse', () => {
expect(reverse('hello')).toEqual('olleh');
expect(reverse('')).toEqual('');
});
Для тестов Jest предоставляет две глобальные функции: test
и expect
. Они доступны без какого-либо импорта, так как Jest делает их глобальными функциями.
Функция test
нужна для описания конкретного теста и его проверок. Самих тестовых функций может быть любое количество. Первым параметром эта функция принимает произвольную строчку, которая должна описывать сам тест. Эта строчка потом отображается на экране во время запуска тестов для упрощения отладки.
NODE_OPTIONS=--experimental-vm-modules npx jest
PASS __tests__/index.test.js
✓ reverse (11ms) # название теста
Второй параметр — функция, внутри которой описан проверочный код. Обратите внимание на то, что этот код не выполняется сразу. Функция test
добавляет его внутрь Jest, который уже решает, как и когда запускать тесты. Это позволяет проводить различные оптимизации, например, выполнять тесты параллельно.
Самое необычное в этом коде — проверки. Jest использует «матчеры» (matchers). Это утверждения, имеющие особую структуру, напоминающую обращение к объекту. Общий принцип работы матчеров такой:
- Вызывается функция
expect()
, куда передаётся актуальное (фактическое) значение. - На результате, возвращаемом функцией
expect()
, вызывается подходящий матчер, например,toEqual
.
Код с матчерами похож на обычные предложения на английском языке. Это сделано специально, чтобы их могли читать даже не программисты:
// Ожидается, что результат выражения reverse('hello') равен 'olleh'
expect(reverse('hello')).toEqual('olleh');
Подробнее о матчерах в следующем уроке.
Одна из приятнейших особенностей Jest — то, как он выводит сообщения о проваленных проверках. Попробуйте внести ошибку в исходную функцию и запустите тесты заново:
NODE_OPTIONS=--experimental-vm-modules npx jest
FAIL __tests__/index.test.js
✕ reverse (9ms)
● reverse
expect(received).toEqual(expected) // Object.is equality
Expected: "olleh"
Received: "o|l|l|e|h"
3 | test('reverse', () => {
4 | const str = 'hello';
> 5 | expect(reverse(str)).toEqual('olleh');
| ^
6 | })
7 |
at Object.toEqual (__tests__/index.test.js:5:24)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 1.683s
Ran all test suites.
В этом выводе показаны не только ожидаемое и фактическое значение, но и исходный код файла с тестами с указанием на конкретную проверку. Это невероятно полезная фишка, которая значительно ускоряет анализ результатов тестирования и помогает в отладке.
Самостоятельная работа
- Выполните все шаги из этого урока
- Залейте код на Гитхаб
Пример полностью настроенного пакета: https://github.com/hexlet-boilerplates/nodejs-package
Дополнительные материалы

Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Урок «Как эффективно учиться на Хекслете»
- Вебинар «Как самостоятельно учиться»
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.