Snapshot-тестирование

Snapshot-тестирование — это метод контроля внешнего вида компонентов, позволяющий фиксировать текущую структуру DOM и автоматически проверять её изменения при последующих обновлениях кода. В контексте Chakra UI, где компоненты часто динамически стилизуются с использованием темы и пропсов, snapshot-тесты помогают обнаруживать непреднамеренные изменения в визуальном и структурном представлении интерфейса.

Установка и подготовка среды

Для работы с snapshot-тестами в проекте на React обычно используют Jest совместно с React Testing Library. Chakra UI интегрируется с этими инструментами без дополнительных плагинов, однако рекомендуется использовать @chakra-ui/react вместе с @testing-library/react для корректного рендеринга компонентов с темой.

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

npm install --save-dev jest @testing-library/react @testing-library/jest-dom

Для корректного тестирования компонентов Chakra UI необходимо оборачивать их в ChakraProvider с вашей темой:

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

const theme = extendTheme({
  colors: {
    brand: {
      100: '#f7caca',
      900: '#702626',
    },
  },
});

const renderWithChakra = (ui) => {
  return render(<ChakraProvider theme={theme}>{ui}</ChakraProvider>);
};

Этот подход гарантирует, что все компоненты тестируются с реальными значениями темы, что особенно важно для snapshot-тестирования.

Создание snapshot-теста

Snapshot-тест фиксирует результат рендера компонента. Пример для кнопки Chakra UI:

import { Button } from '@chakra-ui/react';
import { renderWithChakra } from './test-utils';

test('Button snapshot', () => {
  const { asFragment } = renderWithChakra(<Button colorScheme="brand">Click me</Button>);
  expect(asFragment()).toMatchSnapshot();
});

Пояснение ключевых моментов:

  • asFragment() возвращает фрагмент DOM после рендера.
  • toMatchSnapshot() сохраняет снимок в файле __snapshots__ рядом с тестом.
  • При последующих запусках Jest сравнивает текущий фрагмент с сохранённым snapshot и уведомляет о расхождениях.

Тестирование динамических пропсов

Chakra UI предоставляет мощную систему пропсов для управления стилями. Snapshot-тестирование особенно полезно, когда компоненты изменяют своё состояние на основе пропсов:

test('Button with different sizes', () => {
  const { asFragment: small } = renderWithChakra(<Button size="sm">Small</Button>);
  const { asFragment: large } = renderWithChakra(<Button size="lg">Large</Button>);
  
  expect(small()).toMatchSnapshot();
  expect(large()).toMatchSnapshot();
});

Это фиксирует визуальные различия, обеспечивая контроль над соответствием дизайну.

Стилизация и тема

Chakra UI поддерживает темы, включающие цвета, типографику и брейкпоинты. При snapshot-тестировании важно учитывать использование кастомной темы, иначе снимки будут неинформативны:

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

test('Box with custom theme color', () => {
  const { asFragment } = renderWithChakra(
    <Box bg="brand.100" p={4}>
      Content
    </Box>
  );
  expect(asFragment()).toMatchSnapshot();
});

Snapshot сохранит точное значение стиля bg="brand.100" и отступы p={4}, что позволяет выявлять случайные изменения в CSS или в системе пропсов.

Подход к обновлению снимков

При сознательных изменениях дизайна snapshot необходимо обновлять:

jest -u

Обновление снимков — осознанный процесс. Важная практика: перед обновлением проверять изменения визуально или через Storybook, чтобы избежать автоматического принятия некорректных изменений.

Ограничения snapshot-тестирования

  • Не заменяет визуальное тестирование: snapshot фиксирует структуру DOM, но не отображение в браузере. Для проверки визуальной точности лучше использовать инструменты визуального регрессионного тестирования.
  • Чувствительность к незначительным изменениям: даже добавление атрибута может привести к падению теста.
  • Динамические значения: использование случайных идентификаторов или дат потребует мокирования, чтобы снимок оставался стабильным.

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

Комбинация snapshot-тестов с Storybook позволяет автоматизировать контроль за компонентами Chakra UI на всех вариациях. Storyshots (плагин для Jest) интегрируется с Storybook:

import initStoryshots from '@storybook/addon-storyshots';
initStoryshots();

Это создаёт snapshot-тесты для каждой истории компонента, гарантируя соответствие всех визуальных состояний.

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

  • Создавать отдельный файл для snapshot-тестов, например ComponentName.snapshot.test.js.
  • Использовать обёртку с ChakraProvider для всех компонентов.
  • Мокировать динамические значения (даты, случайные идентификаторы).
  • Разделять тесты на разные пропсы и состояния компонента, чтобы изменения были локализованы.

Snapshot-тестирование в Chakra UI обеспечивает надёжный контроль над визуальной консистентностью компонентов и помогает обнаруживать непреднамеренные изменения в UI, сохраняя целостность интерфейса при развитии проекта.