Создание первых snapshot тестов

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

Установка и настройка

Для начала работы с React Testing Library и написания snapshot-тестов необходимо установить несколько зависимостей. Это включает в себя саму библиотеку для тестирования и Jest, который будет заниматься выполнением и отслеживанием изменений снимков:

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

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

Основные принципы snapshot-тестирования

Snapshot тесты сохраняют результат рендера компонента в отдельном файле. Этот файл обычно хранится в папке __snapshots__, которая автоматически создаётся Jest во время выполнения тестов. Снимок представляет собой строку, которая описывает структуру компонента и его содержимое.

Написание первого snapshot-теста

Предположим, есть компонент Button, который отображает кнопку с текстом. Для тестирования такого компонента с использованием React Testing Library и snapshot-тестирования, нужно выполнить несколько шагов.

Пример компонента:

// Button.js
const Button = ({ label }) => {
  return <button>{label}</button>;
};

export default Button;

Теперь напишем тест для этого компонента с использованием React Testing Library и snapshot-тестирования:

// Button.test.js
import React from 'react';
import { render } from '@testing-library/react';
import Button from './Button';

test('renders Button component and matches snapshot', () => {
  const { asFragment } = render(<Button label="Click me" />);
  expect(asFragment()).toMatchSnapshot();
});

Пояснение к коду

  1. render — функция из React Testing Library, которая рендерит компонент в виртуальный DOM для тестирования.
  2. asFragment — метод, предоставляемый React Testing Library, который возвращает фрагмент рендеренного компонента, представляющий его DOM-структуру. Это позволяет создать снимок компонента, который будет сравниваться в дальнейшем.
  3. toMatchSnapshot — Jest-метод, который сравнивает текущий рендер компонента с ранее сохранённым снимком. Если снимок отсутствует, Jest создаст новый и сохранит его для дальнейших тестов.

Как работает Jest с snapshot-тестами

Когда выполняется первый тест, Jest создаёт файл снимка с данными рендера компонента. Этот файл обычно выглядит как строка с сериализованным DOM. После выполнения теста вы увидите в консоли сообщение о том, что был создан новый снимок:

Test suite failed to run
  New snapshot was not written for: 
  Snapshot name: Button renders Button component and matches snapshot

Этот снимок сохраняется в директории __snapshots__, которая обычно располагается рядом с тестом. В последующих запусках тестов Jest будет сравнивать текущий рендер с уже существующим снимком. Если разница в рендере компонента существует, Jest сообщит об этом:

Test suite failed to run
  Snapshot name: Button renders Button component and matches snapshot
  Snapshot comparison failed

Управление снимками

Если вы намеренно изменили компонент (например, добавили новый элемент), можно обновить снимки, чтобы зафиксировать новое состояние компонента. Для этого достаточно выполнить команду:

npm test -- -u

Эта команда обновит все устаревшие снимки, заменив их на текущие рендеры компонентов.

Зачем нужны snapshot-тесты

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

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

Преимущества и ограничения snapshot-тестов

Преимущества:

  • Автоматизация тестирования UI: Снимки позволяют быстро зафиксировать изменения и своевременно их отслеживать.
  • Понимание изменений в компоненте: Если после изменений в компоненте появляются ошибки, можно быстро сравнить текущий снимок с прежним, чтобы увидеть, что именно изменилось.

Ограничения:

  • Может стать тяжёлым для больших проектов: С увеличением количества компонентов и снимков тесты могут становиться сложными для поддержания.
  • Не проверяет логику и поведение: Snapshot-тесты не проверяют правильность работы логики компонента, их цель — проверка UI.
  • Может привести к ложным срабатываниям: Если компонент изменяет незначительные детали, которые не влияют на функциональность, но изменяют его внешний вид, это приведёт к постоянному обновлению снимков.

Оптимизация snapshot-тестов

Чтобы уменьшить количество обновлений снимков, можно использовать некоторые подходы:

  1. Избегание динамических данных: Компоненты, содержащие динамические данные, такие как даты или случайные числа, могут приводить к изменению снимков при каждом запуске тестов. Чтобы избежать этого, можно использовать мок-данные или тестировать компоненты с фиксированными значениями.

  2. Проверка только важных частей компонента: Вместо того чтобы делать снимок всего компонента, можно сфокусироваться только на его ключевых частях, таких как текст, классы или атрибуты.

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

Заключение

Snapshot-тестирование — мощный инструмент для проверки UI-компонентов в React. Оно позволяет автоматически отслеживать изменения в рендере компонентов и предотвращать случайные изменения интерфейса. Несмотря на все его преимущества, важно не забывать, что snapshot-тесты должны использоваться в сочетании с другими видами тестов, чтобы обеспечить комплексную проверку компонентов.