Testing Library интеграция

Для интеграции Chakra UI с библиотекой тестирования рекомендуется использовать @testing-library/react. Это позволяет рендерить компоненты Chakra UI в изолированном окружении и проверять их поведение и визуальное состояние.

Установка необходимых пакетов:

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

Для корректной работы компонентов Chakra UI важно оборачивать их в ChakraProvider при тестировании. Это можно сделать с помощью вспомогательной функции renderWithChakra:

import { render } from '@testing-library/react';
import { ChakraProvider } from '@chakra-ui/react';

export function renderWithChakra(ui, options) {
  return render(<ChakraProvider>{ui}</ChakraProvider>, options);
}

Теперь все тесты, использующие эту функцию, будут корректно отображать стили и темы Chakra UI.


Тестирование базовых компонентов

Кнопки (Button)

Компоненты Button можно тестировать на наличие текста, состояния disabled и реакции на события клика:

import { Button } from '@chakra-ui/react';
import { renderWithChakra } from './test-utils';
import userEvent from '@testing-library/user-event';

test('кнопка рендерится и реагирует на клик', async () => {
  const handleClick = jest.fn();
  const { getByText } = renderWithChakra(
    <Button onCl ick={handleClick}>Нажми меня</Button>
  );

  const button = getByText('Нажми меня');
  expect(button).toBeInTheDocument();

  await userEvent.click(button);
  expect(handleClick).toHaveBeenCalledTimes(1);
});

Ключевой момент — использование userEvent вместо fireEvent для более реалистичного взаимодействия с компонентом.

Проверка состояний (isDisabled, isLoading)

test('кнопка с состоянием disabled', () => {
  const { getByText } = renderWithChakra(
    <Button isDisabled>Запрещено</Button>
  );

  const button = getByText('Запрещено');
  expect(button).toBeDisabled();
});

test('кнопка с состоянием загрузки', () => {
  const { getByRole } = renderWithChakra(
    <Button isLoading>Загрузка</Button>
  );

  const button = getByRole('button');
  expect(button).toHaveAttribute('aria-busy', 'true');
});

Тестирование форм и интерактивных компонентов

Поля ввода (Input)

Проверка ввода текста и состояния компонента:

import { Input } from '@chakra-ui/react';

test('поле ввода принимает текст', async () => {
  const { getByPlaceholderText } = renderWithChakra(
    <Input placeholder="Введите имя" />
  );

  const input = getByPlaceholderText('Введите имя');
  await userEvent.type(input, 'Алексей');
  expect(input).toHaveValue('Алексей');
});

Выпадающие списки (Select)

import { Sel ect } from '@chakra-ui/react';

test('выбор опции в Sel ect', async () => {
  const { getByRole } = renderWithChakra(
    <Select>
      <option value="1">Опция 1</option>
      <option value="2">Опция 2</option>
    </Select>
  );

  const sel ect = getByRole('combobox');
  await userEvent.selectOptions(select, '2');
  expect(select.value).toBe('2');
});

Тестирование модальных окон (Modal)

Для тестирования Modal важно проверять открытие, закрытие и содержимое. При этом модальные окна рендерятся в Portal, поэтому может понадобиться использовать container или document.body:

import { Modal, ModalOverlay, ModalContent, ModalBody, ModalCloseButton } fr om '@chakra-ui/react';

test('открытие и закрытие модального окна', async () => {
  const { getByText, queryByText } = renderWithChakra(
    <Modal isOpen onCl ose={() => {}}>
      <ModalOverlay />
      <ModalContent>
        <ModalCloseButton />
        <ModalBody>Содержимое модалки</ModalBody>
      </ModalContent>
    </Modal>
  );

  expect(getByText('Содержимое модалки')).toBeInTheDocument();

  const closeButton = getByText('×');
  await userEvent.click(closeButton);

  // Если onClose не изменяет состояние, содержимое останется, но в реальных тестах состояние должно быть мокировано
});

Тестирование тем и адаптивного дизайна

Chakra UI поддерживает темы и цветовые режимы (light/dark). Для проверки корректной работы темы можно использовать контекст ChakraProvider с кастомной темой:

import { extendTheme, Box } fr om '@chakra-ui/react';

const customTheme = extendTheme({
  colors: {
    brand: {
      500: '#ff0000',
    },
  },
});

test('проверка кастомной темы', () => {
  const { getByText } = render(
    <ChakraProvider theme={customTheme}>
      <Box color="brand.500">Текст брендового цвета</Box>
    </ChakraProvider>
  );

  const box = getByText('Текст брендового цвета');
  expect(box).toHaveStyle({ color: '#ff0000' });
});

Проверка анимаций и переходов

Компоненты Chakra UI могут использовать framer-motion для анимаций. Для юнит-тестов анимации часто отключают, чтобы тесты оставались стабильными:

import { Collapse } fr om '@chakra-ui/react';

test('Collapse раскрывается', () => {
  const { getByText } = renderWithChakra(
    <Collapse in={true}>
      <div>Контент</div>
    </Collapse>
  );

  expect(getByText('Контент')).toBeVisible();
});

Использование in={true} гарантирует, что контент сразу виден, без ожидания анимации.


Практические советы

  • Все компоненты, использующие контекст Chakra UI (theme, colorMode, Portal), должны оборачиваться в ChakraProvider.
  • userEvent предпочтителен перед fireEvent для имитации пользовательского взаимодействия.
  • Для тестов компонентов с анимацией или переходами рекомендуется отключать анимацию через motion или использовать фиктивные пропсы.
  • Для проверки стилей можно использовать @testing-library/jest-dom с матчерами toHaveStyle, toBeVisible и toHaveAttribute.
  • Компоненты, рендерящиеся в Portal (Modal, Popover, Drawer), требуют особого внимания к контейнеру рендера и состоянию isOpen.

Эти подходы обеспечивают стабильное, предсказуемое тестирование интерфейсов на базе Chakra UI с использованием Testing Library.