Главная / Статьи / Тестирование компонентов React с помощью Vitest и Testing Library

Тестирование компонентов React с помощью Vitest и Testing Library

Подключите Wire Vitest к Vite, разместите тесты поведения, запустите сравнение результатов в реальном времени и с CI, а также дайте указания ИИ-агенту следовать циклу проверки красного/зеленого цвета.

773 слов

Vitest — это быстрый тест-раннер, разработанный специально для Vite; он кажется знакомым тем, кто работал с Jest, и отлично сочетается с React Testing Library для тестирования поведения компонентов. В этом руководстве рассматриваются настройка, практический цикл «красный-зелёный», структура файлов, а также способы дачи указаний искусственному интеллекту-кодеру, чтобы он помогал, а не создавал беспорядок.

1. Настройка проекта

Установите стандартный набор инструментов для тестирования React в качестве зависимостей разработки:

npm install -D vitest jsdom @testing-library/react @testing-library/jest-dom @testing-library/user-event

Для проекта на Vite и React необходимо указать Vitest информацию об приложении в файле vite.config.ts, чтобы псевдонимы и плагины совпадали с версиями, используемыми в производстве:

For a Vite React project, add Vitest to vite.config.ts:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
  plugins: [react()],
  test: {
    environment: 'jsdom',
    setupFiles: ['./src/test/setup.ts'],
    globals: true,
  },
})

Параметр environment: 'jsdom' предоставляет API DOM без реального браузера. Небольшой файл настроек регистрирует мэтчеры jest-dom один раз для каждого набора тестов:

import '@testing-library/jest-dom/vitest'

Подключите этот файл с помощью опции setupFiles в Vitest, чтобы утверждения вроде toBeInTheDocument и toHaveAccessibleName работали везде.

2. Рекомендуемый процесс работы

Используйте строгую циклическую структуру: Функциональность → Тестирование → Реализация → Проверка → Рефакторинг.

  1. Понимание функциональности — перечислите поведение, видимое для пользователя, и важные состояния (загрузка, успех, ошибка, пустота, отключено). Опишите границы API или браузера, которые требуют имитации, чтобы тесты оставались детерминистичными.
  2. Сначала напишите тест — предпочитайте запросы из React Testing Library; проверяйте результаты, заметные пользователю, а не внутренние состояния; для большей реалистичности используйте userEvent для имитации кликов и ввода.
  • Реализуйте минимум — сосредоточьтесь на том, чтобы код в продакшене выполнял требования не проходящих тестов; избегайте элементов, предназначенных исключительно для тестирования, или утечек внутренних деталей, если нет более чистого решения.
  • Запускайте целевые тесты во время итераций, чтобы обратная связь поступала за секунды, а не минуты:
  • npx vitest run src/components/Button.test.tsx
    
    During development:
    

    Режим наблюдения для локального цикла обратной связи:

    npx vitest
    
    Run the full suite
    

    Полный набор тестов через скрипт npm, указанный в вашем package.json:

    npm test
    

    или однократный запуск в стиле CI без функций наблюдения:

    npx vitest run
    
    Check coverage when appropriate
    

    Анализ покрытия для выявления непроверенных веток:

    npx vitest run --coverage
    

    Рассматривайте показатель покрытия как ориентир, а не просто красивую цифру — отдавайте предпочтение значимым утверждениям перед стремлением к 100%.

    3. Структура тестов

    Размещайте тесты рядом с компонентами, которые они защищают:

    src/
    ├── components/
    │   ├── LoginForm.tsx
    │   └── LoginForm.test.tsx
    ├── hooks/
    │   ├── useUser.ts
    │   └── useUser.test.ts
    ├── pages/
    │   ├── Dashboard.tsx
    │   └── Dashboard.test.tsx
    └── test/
        ├── setup.ts
        └── mocks/
    
    For a component, structure tests around behavior:
    

    Формируйте структуры вокруг результатов действий пользователя, а не названий методов:

    describe('LoginForm', () => {
      it('allows a user to submit valid credentials', async () => {
        // arrange
        // act
        // assert
      })
    
      it('shows validation errors for invalid input', async () => {
        // ...
      })  it('disables submission while logging in', async () => {
        // ...
      })
    })
    

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

    4. Работа с ИИ-агентом для кодирования

    4. Vitest-agent prompt
    

    Инструктируйте агента как опытного инженера по тестированию в React: сначала напишите или обновите несработавший тест, внесите минимальные изменения, затем проверьте их с помощью Vitest и проведите типовую проверку:

    npx vitest run <target-test>
    npx vitest run
    npm run typecheck
    npm run lint
    

    Попросите его отдавать предпочтение запросам Testing Library (getByRole, findByText) перед нестабильными CSS-селекторами, имитировать сетевые ограничения вместо обращения к состоянию компонента, а также оставлять краткую запись, когда тест фиксирует умышленное ограничение продукта.

    Привычки завершения работы

    Сохраняйте конфигурацию Vitest в совместном доступе с Vite, чтобы пути и плагины соответствовали продакшен-среде. В CI предпочитайте использовать команду run, а локально — наблюдать за процессом. Расширяйте наборы тестов по мере добавления новых функций, а не путем кардинальной переработки. Благодаря такому циклу — сначала тест, затем реализация, проверка — React-приложения остаются пригодными к рефакторингу, не замедляя цикл обратной связи, основанный на Vite, который изначально сделал Vitest привлекательным.