Jest¶
Jest - это многофункциональный интегрированный набор модульных тестов, написанный компанией Facebook, включающий программу запуска тестов, поддержку различных окружений, расширяемую библиотеку утверждений, средства мокинга и измерения покрытия.
Стартовый шаблон
В официальном каталоге vite starter templates также имеется шаблон ts-jest
, в котором уже установлен Jest и большинство других требований:
1 2 3 |
|
Если он установлен, продолжите расширенную установку.
Установка¶
Сначала нам необходимо установить пакет jest
:
1 2 3 |
|
Настройка¶
Чтобы протестировать код Solid с помощью Jest, необходимо его настроить. Настройку можно выполнить в поле "jest"
файла package.json
или в отдельном файле jest.config.js
. Последний позволяет иметь различные настройки, тестировать код как на стороне клиента, так и на стороне сервера, а также программно дополнять существующие пресеты.
На момент написания статьи Jest официально поддерживает непосредственно только формат модулей CJS и использует конвейер трансформации для работы с другими форматами и транспилированным JS. Поскольку Solid использует транспонированный код, нам необходимо его настроить.
Поскольку Jest запускает весь импортируемый код в формате CJS, нам нужно либо преобразовать файлы, которые не являются корректным CJS, либо заставить Jest игнорировать их.
Преобразование кода Solid¶
Существует несколько способов преобразования Solid-кода: наиболее предпочтительным является пресет под названием solid-jest
, содержащий конфигурацию для преобразования Solid JSX в CJS. Сначала нам необходимо установить его, если мы не хотим использовать ts-jest
для преобразования TypeScript (см. ниже):
1 2 3 |
|
Чтобы добавить его в нашу конфигурацию Jest, необходимо в свойство preset
конфигурации (в файле package.json#jest
или jest.config.js
) добавить правильный экспорт для тестирования на стороне клиента или на стороне сервера:
1 2 3 |
|
TypeScript преобразование кода¶
Альтернатива 1: Использование babel для преобразования TypeScript¶
Если мы используем babel для преобразования TypeScript, нам необходимо установить @babel/preset-typescript
:
1 2 3 |
|
Также необходимо настроить конфигурацию babel, если ее еще нет:
1 2 3 4 5 6 7 8 9 |
|
Альтернатива 2: Использование ts-jest для преобразования TypeScript¶
Для этого не требуется `solid-jest. Вместо того чтобы использовать только babel-трансформер, мы можем использовать компилятор TypeScript для преобразования тестов. Это означает, что перед выполнением тесты будут статически проверены на соответствие типам. Хотя это и снижает скорость выполнения тестов, но может привести к обнаружению ошибок в коде тестов.
Для использования этого компилятора его необходимо установить:
1 2 3 |
|
Затем необходимо настроить Jest на его использование в файле package.json#jest
или jest.config.js
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Если мы хотим протестировать код так, как он будет работать в браузере, нам также необходимо присвоить псевдоним solid-модулям правильной версии, поскольку ts-jest
, к сожалению, не может определить браузерный режим. Добавьте к предыдущей конфигурации следующее:
1 2 3 4 5 6 |
|
Игнорирование некоторых файлов¶
Как уже говорилось, Jest будет рассматривать все импортированное (включая CSS, изображения) как CJS. Это может привести к ошибкам. Чтобы заставить Jest игнорировать их, создайте пустой файл:
1 |
|
А затем создайте псевдоним для любого файла, который может привести к ошибкам в конфигурации Jest:
1 2 3 4 5 |
|
Однако это может изменить поведение вашего кода. Если вам нужно проверить наличие имен классов HTML, предоставляемых модулями CSS, это не сработает.
Другие преобразования¶
Существует несколько преобразований для других типов файлов.
- CSS-модули:
jest-css-modules-transform
. - SCSS:
jest-scss-transform
. - Импорт пути для обычных файлов:
jest-file-loader
. - JSON5:
@talabes/json5-jest
- GraphQL:
@graphql-tools/jest-transform
. - Web Worker:
jest-webworker
. - подробнее о npmjs
Если поиск подходящей трансформации не дал результата, то решением может стать пользовательская трансформация.
Мы можем просто установить их пакеты, как и раньше, только замените [transform-module]
на указанное выше имя модуля:
1 2 3 |
|
Самый простой способ их использования - дополнить существующий пресет в файле jest.config.js
. В противном случае необходимо вручную объединить содержимое пресета и дополнительные преобразования:
1 2 3 4 5 |
|
В случае если мы хотим придерживаться конфигурации в файле package.json#jest
, нам необходимо скопировать в объявления трансформаций включенные трансформации для файлов .jsx
и .tsx
:
1 2 3 4 5 6 |
|
Окружение¶
Solid.js может работать как в браузере, так и на сервере. По умолчанию Jest тестирует все в окружении node. Чтобы протестировать браузерный код с помощью Jest без реального браузера, нам необходимо DOM-окружение. Стандартом де-факто является jsdom
. Чтобы использовать его, необходимо установить его вместе со средой Jest:
1 2 3 |
|
Также необходимо добавить окружение в конфигурацию Jest в файле package.json#jest
или jest.config.js
:
1 |
|
Запуск тестов¶
Наконец, мы можем добавить в package.json следующий скрипт для вызова интерфейса командной строки Jest:
1 2 3 4 5 |
|
Если наш тест работает, то вывод выглядит примерно так:
1 2 3 4 5 6 7 8 9 10 |
|
Тестирование кода с помощью testing-library¶
Бесспорным золотым стандартом тестирования компонентов на сегодняшний день является библиотека Testing Library Кента Доддса, которая изначально была написана для React, но существует множество портов для других библиотек, и Solid не является исключением.
Установка testing-library¶
Для тестирования с помощью @solidjs/testing-library
нам сначала нужно установить ее:
1 2 3 |
|
Testing-library также предоставляет небольшое полезное расширение для встроенных утверждений jest под названием @testing-library/jest-dom
, которое мы также можем установить:
1 2 3 |
|
Теперь нам нужно запустить его перед тестом, чтобы мы могли использовать расширенные утверждения. Мы можем либо включить его вручную в наши тесты, либо, что более удобно, включить его в setupFiles
нашей конфигурации Jest:
1 2 3 4 5 |
|
Есть еще одно полезное дополнение от Testing Library для тестирования пользовательских событий: @testing-library/user-events
. Оно пытается воспроизвести реальные события, которые обычно происходят в ситуации с пользователем, например, он фокусирует поля ввода перед тем, как набрать в них текст. Если мы хотим протестировать сложную интерактивность, то следует установить и ее.
1 2 3 |
|
Тестирование компонентов¶
Давайте протестируем наш самый простой пример - счетчик. Рассмотрим следующий компонент, который вы могли видеть на игровой площадке:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Мы хотим проверить, есть ли кнопка, которая подсчитывает количество нажатий; чтобы убедиться, что она работает не один раз, мы попробуем сделать это во второй раз, так что вот как выглядит наш тест:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Для использования toHaveTextContent
необходимо, чтобы у нас была установлена @testing-library/jest-dom
, в противном случае необходимо заменить ее на
1 |
|
что немного менее разборчиво, и в случае неудачи сообщение об ошибке будет менее полезным.
Если мы не хотим использовать userEvent
, мы можем также использовать fireEvent
из @solidjs/testing-library
, который является синхронным, но имейте в виду, что эти события менее похожи на реальные события пользователя и в некоторых случаях могут давать разные результаты в зависимости от контекста.
Тестирование логики многократного использования¶
Логика многократного использования, также известная как хуки или примитивы, также может быть протестирована с помощью @solidjs/testing-library
, используя функцию renderHook
.
Рассмотрим хук, который выдает нам текст "Lorem ipsum" с определенным количеством слов. Мы хотим протестировать его с 3, 2 и 5 словами, чтобы убедиться, что он работает (выберите lorem.test.ts
):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Тестирование пользовательских директив¶
Solid.js обладает полезной способностью делать многоразовыми не только логические, но и DOM-взаимодействия с помощью так называемых пользовательских директив. Очевидно, что тестирование таких директив должно быть таким же удобным, как и тестирование хуков, поэтому в нашей библиотеке тестирования имеется утилита renderDirective
.
Примитив, который мы хотим протестировать, - это onClickOutside
, который вызывает функцию, указанную в его аргументе, и нам нужно протестировать его, щелкнув мышью внутри и снаружи, и проверить, была ли вызвана наша функция:
1 2 3 4 5 6 7 8 9 10 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|