Интеграция с webpack, Vite и другими бандлерами

React Testing Library (RTL) строится на принципах тестирования компонентов React максимально близко к поведению пользователя. Для эффективного использования в проектах важно интегрировать библиотеку с бандлерами, такими как Webpack, Vite, Parcel или Rollup, чтобы тесты корректно обрабатывали JSX, модули и стили.


Интеграция с Webpack

Webpack является наиболее распространённым бандлером для React-проектов. Для корректной работы RTL необходимо обеспечить поддержку JSX и современных возможностей ES6+.

1. Установка зависимостей

npm install --save-dev @testing-library/react @testing-library/jest-dom babel-jest @babel/preset-env @babel/preset-react jest webpack
  • @testing-library/react – основная библиотека для тестирования компонентов.
  • @testing-library/jest-dom – расширение для удобной проверки DOM-элементов.
  • babel-jest и пресеты Babel – для трансформации JSX и ES6 в формат, понятный Jest.
  • jest – тестовый раннер, интегрируемый с Webpack через конфигурацию.

2. Настройка Babel

Файл .babelrc или babel.config.json должен содержать:

{
  "presets": ["@babel/preset-env", "@babel/preset-react"]
}

Это обеспечивает корректную трансформацию современного JavaScript и JSX, чтобы тесты могли выполняться вне браузера.

3. Настройка Jest для Webpack-проектов

{
  "jest": {
    "moduleFileExtensions": ["js", "jsx"],
    "transform": {
      "^.+\\.(js|jsx)$": "babel-jest"
    },
    "moduleNameMapper": {
      "\\.(css|scss)$": "identity-obj-proxy"
    },
    "setupFilesAfterEnv": ["@testing-library/jest-dom/extend-expect"]
  }
}
  • moduleNameMapper позволяет игнорировать импорты CSS или SCSS.
  • setupFilesAfterEnv подключает расширения RTL автоматически перед запуском тестов.

4. Тестирование компонентов с Webpack

Компоненты можно тестировать стандартными методами RTL:

import { render, screen } from '@testing-library/react';
import Button from './Button';

test('должен отображать текст кнопки', () => {
  render(<Button text="Нажми меня" />);
  expect(screen.getByText('Нажми меня')).toBeInTheDocument();
});

Webpack в этом случае не требует дополнительной конфигурации для базового рендера, так как трансформация JSX выполняется через Babel.


Интеграция с Vite

Vite использует нативный ES-модульный подход и быстрый HMR. Его интеграция с RTL отличается простотой.

1. Установка зависимостей

npm install --save-dev vitest @testing-library/react @testing-library/jest-dom @vitejs/plugin-react
  • vitest – тестовый раннер, встроенный в экосистему Vite.
  • @vitejs/plugin-react – необходим для обработки JSX и Fast Refresh.

2. Конфигурация Vite

Файл vite.config.js:

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: './src/setupTests.js'
  }
});
  • environment: 'jsdom' имитирует браузерное окружение.
  • setupFiles позволяет подключить расширения RTL.

3. Настройка setupTests.js

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

4. Пример теста для Vite

import { render, screen } from '@testing-library/react';
import Input from './Input';

test('поле ввода отображает placeholder', () => {
  render(<Input placeholder="Введите текст" />);
  expect(screen.getByPlaceholderText('Введите текст')).toBeInTheDocument();
});

Vite автоматически обрабатывает импорты компонентов и стилей, поэтому дополнительных мапперов не требуется.


Особенности интеграции с другими бандлерами

Parcel:

  • Минимальная конфигурация, так как Parcel умеет обрабатывать JSX и CSS без явного конфигурирования.
  • Для тестирования достаточно добавить jest и @testing-library/react.
  • CSS можно игнорировать через identity-obj-proxy.

Rollup:

  • Потребует плагин @rollup/plugin-babel для трансформации JSX.
  • Настройка тестов аналогична Webpack: babel-jest, jest-dom, setupFilesAfterEnv.
  • При использовании TypeScript добавляется @rollup/plugin-typescript.

Работа с CSS и ассетами

Во всех бандлерах важно корректно обрабатывать импорты стилей и изображений.

  • CSS: identity-obj-proxy позволяет использовать классы без ошибок импорта.
  • SVG/изображения: можно создавать моки с помощью jest.mock('*.svg', ...).

Пример для Jest:

jest.mock('./logo.svg', () => 'logo.svg');

Рекомендации по организации тестов

  • Создавать папку __tests__ рядом с компонентами или внутри src.
  • Использовать расширение .test.js или .spec.js для единообразия.
  • Настраивать setupTests.js для общих расширений и моков.
  • Разделять юнит-тесты (логика) и интеграционные (взаимодействие компонентов).

Особенности работы с асинхронными компонентами

  • Использовать findBy* методы RTL для асинхронного рендера.
  • Комбинировать с waitFor для контроля времени появления элементов:
import { render, screen, waitFor } from '@testing-library/react';
import DataLoader from './DataLoader';

test('загруженные данные отображаются', async () => {
  render(<DataLoader />);
  await waitFor(() => expect(screen.getByText('Данные загружены')).toBeInTheDocument());
});

Эта практика критична для компонентов, загружающих данные через API или таймеры.


Поддержка TypeScript

  • Включить ts-jest для Webpack/Rollup или использовать встроенный TypeScript Vite.
  • Конфиг tsconfig.json должен включать:
{
  "jsx": "react-jsx",
  "moduleResolution": "node",
  "esModuleInterop": true,
  "allowSyntheticDefaultImports": true
}
  • Файлы тестов использовать с расширением .test.tsx для корректной работы JSX в TypeScript.

Эта структура интеграции позволяет создавать быстрые, надёжные и читаемые тесты компонентов React, полностью совместимые с современными бандлерами, минимизируя конфликты между JSX, стилями и модульной системой.