Back

Как мигрировать ваши тесты с Enzyme на React Testing Library

Как мигрировать ваши тесты с Enzyme на React Testing Library

Если ваш набор тестов React всё ещё зависит от Enzyme, вы поддерживаете код на основе библиотеки, которая перестала получать официальные обновления несколько лет назад. У Enzyme нет адаптера для React 18 или 19, а неофициальные обходные решения ненадёжны. Путь вперёд очевиден: миграция на React Testing Library (RTL).

Эта статья охватывает концептуальные изменения, необходимые для успешной миграции с Enzyme на React Testing Library, распространённые паттерны рефакторинга и практические рекомендации для команд, решающих эту задачу в 2025 году.

Ключевые выводы

  • У Enzyme отсутствуют официальные адаптеры для React 18 и 19, что делает миграцию на React Testing Library необходимой для современных React-проектов.
  • RTL фокусируется на тестировании поведения, видимого пользователю, а не на деталях реализации, создавая более стабильные и значимые тесты.
  • Замените shallow() и mount() из Enzyme на render() из RTL и используйте доступные запросы, такие как getByRole(), вместо find().
  • Мигрируйте постепенно, запуская обе библиотеки параллельно и конвертируя тесты партиями, начиная с более простых компонентов.

Почему Enzyme больше не жизнеспособен

Enzyme был доминирующим инструментом тестирования React на протяжении многих лет. Но его тесная связь с внутренними механизмами React стала проблемой. Когда вышел React 17, сообщество создало адаптеры, заполнившие пробел. React 18 полностью нарушил эту схему — официального адаптера не существует, и никакого не было анонсировано, поскольку проект Enzyme фактически не поддерживается.

Помимо совместимости, Enzyme поощрял тестирование деталей реализации: проверку внутреннего состояния, вызов методов экземпляра и использование поверхностного рендеринга для изоляции компонентов от их дочерних элементов. Эти паттерны создают хрупкие тесты, которые ломаются при рефакторинге, даже когда поведение остаётся неизменным.

React Testing Library использует противоположный подход. Она полностью рендерит компоненты и запрашивает DOM так, как с ним взаимодействуют пользователи — по роли, метке и текстовому содержимому. Это соответствует современным лучшим практикам тестирования React и создаёт тесты, которые остаются стабильными при изменении реализации.

Основное изменение философии

Самая большая сложность в этой миграции — не синтаксис. Это образ мышления.

Тесты Enzyme часто выглядят так:

  • Доступ к экземпляру компонента через wrapper.instance()
  • Прямой вызов setState() или setProps()
  • Проверка значений внутреннего состояния
  • Использование shallow() для пропуска рендеринга дочерних компонентов

Ни один из этих подходов не имеет прямого эквивалента в RTL. RTL намеренно их исключает, потому что они тестируют то, что пользователи никогда не видят.

Вместо этого тесты RTL фокусируются на:

  • Что отрендерено в DOM
  • Как элементы реагируют на взаимодействие пользователя
  • Присутствуют ли доступные роли и метки

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

Распространённые паттерны рефакторинга

Замените shallow() и mount() на render()

Функция render() из RTL монтирует ваш компонент в DOM-окружение. Эквивалента shallow не существует. Если дочерние компоненты вызывают проблемы, замокируйте их с помощью Jest:

jest.mock('./ChildComponent', () => () => <div data-testid="child-mock" />);

Замените wrapper.find() на доступные запросы

find('button') из Enzyme становится screen.getByRole('button') в RTL. Предпочитайте запросы, которые отражают то, как пользователи находят элементы:

  • getByRole() для интерактивных элементов
  • getByLabelText() для полей форм
  • getByText() для видимого контента

Удалите проверки instance() и state()

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

Обрабатывайте асинхронное поведение с помощью findBy и waitFor

Enzyme требовал ручных вызовов wrapper.update(). RTL обрабатывает обновления автоматически. Используйте findByRole() или waitFor() для асинхронных проверок.

Реальная миграция достижима

Крупные команды успешно завершили эту миграцию. Инженерная команда Slack конвертировала более 15 000 тестов, используя комбинацию кодмодов на основе AST и трансформаций с помощью LLM. Инженерная команда The New York Times описала свою миграцию с Enzyme как самую масштабную часть обновления до React 18.

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

React 19 и будущее тестирования компонентов

React 19 объявляет устаревшим react-test-renderer для тестирования компонентов, ещё больше укрепляя RTL как стандарт. Если вы планируете обновление React, завершение миграции с Enzyme на React Testing Library в первую очередь устраняет серьёзное препятствие.

Современное тестирование React в 2025 году означает написание тестов, которые переживают рефакторинг, проверяют доступность и отражают реальное поведение пользователя. RTL обеспечивает всё это.

Заключение

Миграция с Enzyme требует большего, чем просто поиск и замена. Вы принимаете другую философию тестирования — ту, которая приоритизирует поведение, видимое пользователю, над внутренней реализацией. Усилия окупаются в виде тестов, которые более стабильны, более значимы и совместимы с текущими и будущими версиями React.

Начните с небольшой партии. Переформулируйте свои проверки вокруг того, что видят пользователи. Откажитесь от поверхностного рендеринга. Ваш набор тестов станет от этого только лучше.

Часто задаваемые вопросы

Да. Обе библиотеки могут сосуществовать в одном проекте. Это позволяет мигрировать тесты постепенно, не нарушая существующий набор тестов. Установите RTL вместе с Enzyme, конвертируйте тесты партиями и удалите Enzyme после завершения миграции.

RTL не рекомендует тестировать внутреннее состояние напрямую. Вместо этого тестируйте наблюдаемый результат. Если клик по кнопке изменяет состояние, проверьте, что видит пользователь после клика — например, обновлённый текст, появление нового элемента или изменённый атрибут. Такой подход создаёт более устойчивые тесты.

Замокируйте проблемный дочерний компонент на уровне модуля с помощью Jest. Это изолирует ваш тест от реализации дочернего компонента, при этом всё ещё полностью рендеря родительский компонент. Используйте jest.mock, чтобы заменить дочерний компонент простым элементом-заглушкой.

Да. RTL остаётся рекомендуемой библиотекой тестирования для React 19. React 19 объявляет устаревшим react-test-renderer для тестирования компонентов, делая RTL стандартным выбором. Завершение миграции перед обновлением до React 19 устраняет значительное препятствие совместимости.

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay