Введение в тестирование с Vitest |
20.10.2025 00:00 |
В последнее время я экспериментирую с Vitest — фреймворком для тестирования JavaScript- и TypeScript-приложений. Я начал работать с этим инструментом недавно и был приятно удивлён его возможностями. Как правило, Vitest используют для юнит- и компонентного тестирования, но инструмент может гораздо больше. В этой статье мы рассмотрим его функции и варианты использования. Начнем с основ Если вы, как я, в основном работаете в end-to-end тестировании, то сразу заметите главное отличие подхода к тестированию у инструментов вроде Vitest. В e2e-тестировании вы запускаете приложение в браузере и проходите через определённый пользовательский сценарий. В Vitest вы фокусируетесь на конкретной части приложения. Это может быть компонент, функция или что-то ещё. Подход обычно заключается в том, чтобы импортировать этот фрагмент приложения в тест и проверять различные сценарии изолированно. В качестве примера я буду использовать простое приложение страницы статуса, написанное на Next.js. Приложение отображает текущий статус системы и список предыдущих состояний. В этом приложении у меня есть функция, которая возвращает цвет в зависимости от статуса сервиса. statusData.ts 1 export function getStatusColor(status: Status): string { Цель моего тестирования — убедиться, что функция возвращает правильный цвет для каждого статуса. Тест на Vitest для этой функции выглядел бы так statusData.spec.ts 1 import { test, expect } from "vitest"; Тест просто проверяет все возможные для этой функции случаи и сравнивает возвращаемое значение с ожидаемым. Для такой элементарной функции тест выглядит довольно простым, но подобные тесты становятся особенно полезными, когда нам нужно работать с несколькими функциями, импортами или при рефакторинге существующего функционала. Запуск тестовТут несколько способов запуска тестов. Самый простой — воспользоваться командной строкой: 1 npx vitest Если вы используете VS Code или Cursor, у них есть расширение, которое позволяет запускать тесты прямо в редакторе кода. Также поддерживаются и другие редакторы. Vitest также предлагает очень удобный UI-режим, в котором отображается дашборд всех ваших тестов. Его можно запустить следующей командой: 1 npx vitest --ui UI-режим автоматически запускается в режиме watch — это значит, что при любом изменении теста или исходного файла тест будет перезапущен, и вы сразу получите обратную связь. Тестирование компонентовТак же, как функции, вы можете тестировать и компоненты. Давайте рассмотрим компонент, который использует эти цвета и содержит чуть больше логики. Вот пример компонента, который рендерит отдельный элемент списка. Важно отметить, что этот компонент принимает проп item. Позже мы проверим, что он правильно обрабатывается. historical-status-item.tsx 1 import type { HistoricalStatus } from "../utils/statusData"; Нам нужно сделать ещё пару шагов, чтобы протестировать наш компонент. Для этого его нужно отрендерить и правильно настроить. Мы установим несколько утилит, которые помогут с этим. 1 npm i @vitejs/plugin-react jsdom @testing-library/react @testing-library/jest-dom Эти утилиты расширят возможности Vitest, добавят подходящую среду тестирования и помогут корректно настраивать компоненты для тестирования. Во-первых, нужно подключить плагин react в файл vitest.config.ts, а также задать тестовую среду. vitest.config.ts 1 import { defineConfig } from 'vitest/config' Теперь всё готово к написанию теста. Мы хотим отрендерить компонент <HistoricalStatusItem />. Как уже упоминалось, этот компонент требует передачи данных через пропсы. Мы можем просто создать мок-объект прямо в тесте, передать его в компонент и затем сделать необходимые проверки. historical-status-item.spec.ts 1 import '@testing-library/jest-dom/vitest' Когда мы создали несколько тестов компонентов, имеет смысл вынести повторяющийся код в отдельный файл. Типичный пример — импорт @testing-library/jest-dom, который будет нужен каждый раз, когда мы работаем с DOM-элементами. Этот импорт можно переместить в файл vitest.setup.ts и подключить его как файл настроек в конфигурации. vitest.config.ts 1 import { defineConfig } from 'vitest/config' Компоненты с управляемым состояниемТестирование компонентов, использующих управление состоянием, может быть чуть сложнее. В этом приложении мы используем Zustand для управления состоянием. Компонент отображает статусы системы, полученные из хранилища, и показывает их в виде карточек. current-status.tsx 1 "use client" Чтобы протестировать этот компонент, нам нужно замокать хранилище. Мы не хотим полагаться на реальное управление состоянием в наших тестах. Во многих реальных сценариях доступ к состоянию может быть вовсе невозможен. Именно здесь возможности мокирования Vitest приходятся как нельзя кстати. Мы можем использовать vi.mock(), чтобы перехватить импорт хранилища и подставить собственные данные. Мы просто передаём свои мок-данные туда, где компонент обычно получал бы данные из хранилища. Обычно компонент получает данные с помощью хука useStatusStore, но в этом случае мы используем vi.fn(), чтобы «сказать» компоненту, что теперь хук useStatusStore возвращает именно эти данные. Затем мы проверяем, что все мок-данные были корректно отрисованы в компоненте. current-status.spec.ts 1 import { render, screen } from '@testing-library/react' Это позволяет протестировать, как компонент рендерится и как он себя ведёт при различных состояниях системы, не настраивая всю инфраструктуру управления состоянием. Режим браузераУ Vitest есть ещё одна интересная функция — browser mode. Сейчас она находится в экспериментальной стадии, но уже демонстрирует широкие возможности. Это поднимает тестирование компонентов на новый уровень, так как позволяет рендерить их прямо в браузере — в той самой среде, где они должны использоваться. Вы даже можете взаимодействовать с компонентами с помощью Playwright или Webdriver.io. Установка довольно проста: CLI-утилита поможет вам пройти весь процесс, когда вы запустите команду npx vitest init browser. Это установит все необходимые зависимости и настроит конфигурационный файл за вас. vitest.config.ts 1 import { defineConfig } from 'vitest/config' Теперь наш тест требует небольшого обновления, чтобы компонент отображался внутри браузерной страницы. Мы просто находим базовый элемент с помощью page.elementLocator() и затем используем его для написания проверок компонента. current-status.spec.ts 1 import { render } from '@testing-library/react' Когда вы запустите Vitest в режиме UI, вы увидите новый раздел, где можно просматривать ваш компонент прямо в браузере. При первом запуске вы можете не увидеть стили — в этом случае поможет обновление файла vitest.setup.ts, чтобы подключить CSS-файл напрямую. vitest.setup.ts 1 import '@testing-library/jest-dom/vitest' Покрытие кодаЛично я – большой фанат покрытия кода. Для меня это не погоня за процентами, а способ выявить «слепые зоны» в коде. Раньше я много работал с покрытием в Cypress. Самое крутое в Vitest — то, что для покрытия кода не нужно специально модифицировать приложение. Vitest использует встроенное покрытие движка Chrome V8 для генерации отчётов. Всё, что нужно сделать — это запустить тесты с флагом --coverage: 1 npx vitest --coverage При первом запуске Vitest предложит установить пакет @vitest/coverage-v8. После выполнения тестов отчёт по покрытию будет сохранён в папке coverage, а также доступен прямо в UI-режиме Vitest. ЗаключениеЯ попробовал Vitest из любопытства — и был впечатлён, насколько легко он настраивается и насколько комфортен в работе. Особенно меня порадовал режим браузера — он работает невероятно быстро. То, что взаимодействие с компонентами реализовано через Playwright, даёт, на мой взгляд, огромный потенциал. Компонентное тестирование и e2e стали ближе друг к другу. А в сочетании с покрытием кода, по-моему, мы получаем очень интересную и мощную тестовую связку. Я поэкспериментирую с Vitest побольше и посмотрю на его дальнейшее развитие. |