Среды тестирования

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

Исполнители тестов

Исполнители тестов, такие как Jest, mocha, ava, позволяют писать тесты на JavaScript и запускать их в процессе разработки. Кроме того, наборы тестов запускаются в рамках непрерывной интеграции.

  • Jest хорошо совместим с React-проектами, поддерживает такие возможности, как фиктивные модули и таймеры, работа с jsdom. Если вы используете Create React App, Jest уже предустановлен с полезными настройками по умолчанию.
  • Библиотеки, такие как mocha, хорошо работают в среде с настоящим браузером и помогут в тестах, которым она требуется.
  • «Сквозные» тесты нужны для тестирования длинных последовательностей действий через несколько страниц и требуют другой настройки.

Подмена области рендеринга

Тесты часто запускаются в среде, у которой нет доступа к реальной области рендеринга, например браузера. В этом случае мы рекомендуем имитировать работу браузера с помощью jsdom — легковесной реализации браузера, которая запускается в Node.js.

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

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

Большое количество UI-тестов можно написать описанным выше способом: Jest запускает тесты, компонент рендерится в jsdom, действия пользователя описываются в виде последовательности браузерных событий и оборачиваются вспомогательной функцией act() (пример). Кстати, много тестов для библиотеки React написано таким образом.

Если вы пишете библиотеку, которая в основном тестирует поведение специфичное для браузера, например, работа с разметкой страницы или настоящие элементы input, используйте фреймворк, такой как mocha.

В среде, где вы не можете имитировать DOM (например, тестирование компонентов React Native в Node.js), используйте вспомогательные функции имитации события, чтобы имитировать взаимодействие с элементами. В качестве альтернативы можно использовать вспомогательную функцию fireEvent из @testing-library/react-native.

Фреймворки, такие как Cypress, puppeteer и webdriver полезны для запуска «сквозных» тестов.

Подмена функций

При написании тестов иногда требуется подменить части кода, которые не имеют аналога внутри среды тестирования (например, проверка статуса через navigator.onLine внутри Node.js). Тесты могут «следить» за некоторыми функциями и видеть, как другие части теста взаимодействуют с ними. В этом случае полезно иметь возможность выборочно подменять эти функции на удобные для тестирования версии.

Это особенно удобно при получении данных. Обычно, предпочтительнее использовать «подставные» данные для тестов, чтобы избежать замедления и странного поведения, чем получать данные из настоящих API. (пример). Это сделает тесты более предсказуемыми. Библиотеки, такие как Jest и sinon, поддерживают подмену функций. В «сквозных» тестах, подменить сетевой интерфейс будет тяжелее, но вы, возможно, захотите протестировать и настоящие API в таких тестах.

Фиктивные модули

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

В Node.js исполнители тестов, например Jest поддерживает фиктивные модули. Также вы можете использовать библиотеки, такие как mock-require.

Фиктивные таймеры

Компоненты могут использовать функции, связанные с временем, такие как setTimeout, setInterval или Date.now. В средах тестирования может быть полезно подменить такие функции на фиктивные, что позволит «двигаться» во времени. Это отличный способ ускорить выполнение тестов! Тесты с таймерами будут по-прежнему выполнятся по порядку, только быстрее. (пример). Большинство фреймворков, включая Jest, sinon и lolex, позволяют подменять таймеры в тестах.

Иногда фиктивные таймеры не нужны. Например, при тестировании анимации или взаимодействии с удалённым API, который чувствителен к времени (имеет ограничение по частоте доступа). Библиотеки с фиктивными таймерами позволяют включать и выключать их для одного теста или набора в целом, так что вы можете явно указать как эти тесты будут исполняться.

«Сквозные» тесты

«Сквозные» тесты полезны при тестировании длинных последовательностей действий, особенно тех, что важны для бизнеса (таких как платежи или регистрация пользователей). Для таких тестов, вы скорее всего, хотите протестировать рендеринг всего приложения в настоящем браузере, получение данных из настоящих API, использование сессий и кук, переходы по ссылкам. Ещё вы, возможно, захотите проверить вероятный результат не только состояния DOM, но и сохранения данных (например, проверить были ли изменения сохранены в базе данных).

В этом случае вам стоит использовать фреймворк Cypress, Playwright или библиотеку Puppeteer так вы сможете перемещаться между несколькими маршрутами и проверять вероятные побочные эффекты не только в браузере, но и, возможно, на бэкенде.