Привет, друзья!
В данном туториале мы будем тестировать компоненты на React с помощью Jest и Testing Library.
Список основных задач, которые мы решим на протяжении туториала:
- Создание шаблона
React-приложения
с помощью Vite. - Создание компонента для получения приветствия от сервера.
- Установка и настройка
Jest
. - Установка и настройка
Testing Library
. - Тестирование компонента с помощью
Testing Library
:- Используя стандартные возможности.
- С помощью кастомного рендера.
- С помощью кастомных запросов.
- Тестирование компонента с помощью снимков
Jest
.
Создание шаблона
Обратите внимание: для работы с зависимостями я буду использовать Yarn.
Vite
- это продвинутый сборщик модулей (bundler) для JavaScript-приложений
. Он более производительный и не менее кастомизируемый, чем Webpack.
Vite CLI
позволяет создавать готовые к разработке проекты, в том числе, с помощью некоторых шаблонов.
Создаем шаблон React-приложения
:
# react-testing - название проекта
# --template react - используемый шаблон
yarn vite create react-testing --template react
Переходим в созданную директорию и устанавливаем зависимости:
cd react-testing
yarn
Убедиться в работоспособности приложения можно, выполнив команду yarn dev
.
Приводим структуру проекта к следующему виду:
- node_modules
- src
- App.jsx
- main.jsx
- .gitignore
- index.html
- package.json
- vite.config.js
- yarn.lock
{ task: 'setup project', status: 'done' }
Создание компонента
Для обращения к API
мы будем использовать Axios:
yarn add axios
Создаем в директории src
файл FetchGreeting.jsx
следующего содержания:
import { useState } from 'react'
import axios from 'axios'
// пропом компонента является адрес конечной точки
// для получения приветствия от сервера
const FetchGreeting = ({ url }) => {
// состояние приветствия
const [greeting, setGreeting] = useState('')
// состояние ошибки
const [error, setError] = useState(null)
// состояние нажатия кнопки
const [btnClicked, setBtnClicked] = useState(false)
// метод для получения приветствия от сервера
const fetchGreeting = (url) =>
axios
.get(url)
// если запрос выполнен успешно
.then((res) => {
const { data } = res
const { greeting } = data
setGreeting(greeting)
setBtnClicked(true)
})
// если возникла ошибка
.catch((e) => {
setError(e)
})
// текст кнопки
const btnText = btnClicked ? 'Готово' : 'Получить приветствие'
return (
<div>
<button onClick={() => fetchGreeting(url)} disabled={btnClicked}>
{btnText}
</button>
{/* если запрос выполнен успешно */}
{greeting && <h1>{greeting}</h1>}
{/* если возникла ошибка */}
{error && <p role='alert'>Не удалось получить приветствие</p>}
</div>
)
}
export default FetchGreeting
{ task: 'create component', status: 'done' }
Установка и настройка Jest
Устанавливаем Jest
:
yarn add jest
По умолчанию средой для тестирования является Node.js, поэтому нам потребуется еще один пакет:
yarn add jest-environment-jsdom
Создаем в корне проекта файл jest.config.js
(настройки Jest
) следующего содержания:
module.exports = {
// среда тестирования - браузер
testEnvironment: 'jest-environment-jsdom',
}
Для транспиляции кода перед запуском тестов Jest
использует Babel. Поскольку мы будем работать с JSX нам потребуется два "пресета":
yarn add @babel/preset-env @babel/preset-react
Создаем в корне проекта файл babel.config.js
(настройки Babel
) следующего содержания:
module.exports = {
presets: [
'@babel/preset-env',
['@babel/preset-react', { runtime: 'automatic' }]
]
}
Настройка runtime: 'automatic'
добавляет React
в глобальную область видимости, что позволяет не импортировать его явно в каждом файле.
Дефолтной директорией с тестами для Jest
является __tests__
. Создаем эту директорию в корне проекта.
Создаем в директории __tests__
файл fetch-greeting.test.jsx
следующего содержания:
test.todo('получение приветствия')
Объекты describe
, test
, expect
и другие импортируются в пространство модуля Jest
. Почитать об этом можно здесь и здесь.
test.todo(name: string)
- это своего рода заглушка для теста, который мы собираемся писать.
Добавляем в раздел scripts
файла package.json
команду для запуска тестов:
"test": "jest"
Выполняем эту команду с помощью yarn test
:
Получаем в терминале нашу "тудушку" и сообщение об успешном выполнении "теста".
Кажется, что можно приступать к тестированию компонента. Почти, есть один нюанс.
Дело в том, что Jest
спроектирован для работы с Node.js
и не поддерживает ESM
из коробки. Более того, поддержка ESM
является экспериментальной и в будущем может претерпеть некоторые изменения. Почитать об этом можно здесь.
Для того, чтобы все работало, как ожидается, нужно сделать 2 вещи.
Можно определить в package.json
тип кода как модуль ("type": "module"
), но это сломает Vite
. Можно изменить расширение файла с тестом на .mjs
, но мне такой вариант не нра вится. А можно сообщить Jest
расширения файлов, которые следует обрабатывать как ESM
:
// jest.config.js
module.exports = {
testEnvironment: 'jest-environment-jsdom',
// !
extensionsToTreatAsEsm: ['.jsx'],
}
Также необходимо каким-то образом передать Jest
флаг --experimental-vm-modules
. Существует несколько способов это сделать, но наиболее подходящим с точки зрения обеспечения совместимости с разными ОС является следующий:
- Устанавливаем cross-env с помощью
yarn add cross-env
. - Редактируем команду для запуска тестов:
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest"
{ task: 'setup jest', status: 'done' }
Установка и настройка Testing Library
Устанавливаем обертку Testing Library
для React
:
yarn add @testing-library/react
Для обеспечения интеграции с Jest
нам также потребуется следующий пакет:
yarn add @testing-library/jest-dom
Для тестирования отправки запроса на сервер и получения от него приветствия необходим фиктивный (mock) сервер. Одним из самых простых решений для этого является msw:
yarn add msw
{ task: 'setup testing library', status: 'done' }