Примеры написания тестовых примеров для компонентов высокого порядка и измерения покрытия тестами.

Недавно мы написали статью о Безголовых компонентах пользовательского интерфейса, в которой исследовали компоненты высокого порядка (HOC) и настраиваемые хуки. Следующий вопрос - как писать тестовые примеры и измерять тестовое покрытие. Хотя тестирование пользовательских хуков рассматривается в другой статье, здесь мы рассмотрим примеры того, как тестировать HOC с помощью Jest и библиотеки тестирования React.

Терминологии

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

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

Покрытие тестированием: показатель, измеряющий объем тестирования, выполненного с помощью набора тестовых примеров. Собирается информация о процентном соотношении выполненных операторов, ветвей и т. Д. Также есть указания о том, какие строки еще предстоит протестировать.

Jest: среда тестирования JavaScript для проверки правильности любой кодовой базы JavaScript. Это один из самых популярных средств запуска тестов и выбор по умолчанию для проектов React.

Библиотека тестирования React: легкое решение для тестирования компонентов React. Он предоставляет служебные функции поверх react-dom и react-dom / test-utils для тестирования компонентов React в зависимости от того, как они используются. Библиотека тестирования React вместе с сценариями модульного тестирования Jest и сценариями интеграции.

Компонент высшего порядка: функция, которая принимает компонент и возвращает новый компонент. Это композиционный подход для повторного использования логики компонентов.

Создать приложение React: быстрый способ создать проект React. Таким образом, мы сосредотачиваемся на коде, а не на инструментах создания. Он имеет встроенную библиотеку Jest и React Testing Library, которые являются частью dependencies в package.json:

"dependencies": {
  "@testing-library/jest-dom": "^4.2.4",
  "@testing-library/react": "^9.5.0",
  "@testing-library/user-event": "^7.2.1"
}

Тесты и покрытия для withColor

В статье о безголовых компонентах пользовательского интерфейса мы написали withColor HOC. Это оболочка для настройки цвета базового компонента:

Написание тестового примера аналогично написанию фактического кода в упрощенной и изолированной среде. Для HOC нам нужно создать компонент для упаковки, который может отображать цвет: <div>Test Color</div>. Этот компонент используется для генерации withColor HOC в строке 6 в приведенном ниже тестовом коде:

Строки 7-10 визуализируют тестовый пример моментального снимка, который делает снимок и сохраняет его в каталоге __snapshots__ в качестве ссылки (опция —- updateSnapshot, or -u). Строка 9 сравнивает новый снимок со ссылкой и проверяет, не изменился ли пользовательский интерфейс неожиданно.

Вот сгенерированный снимок эталонного изображения - он похож на представление в браузере:

Снимок представляет собой четкую картину для следующих двух тестовых случаев:

  • Убедитесь, что родительский узел имеет цвет по умолчанию red, если цвет не указан (строки 12-15).
  • Убедитесь, что родительский узел имеет цвет blue, если цвет указан как blue (строки 17-20).

Затем мы можем запустить тесты: npm test.

Он будет запускаться App.test.js и withColor.test.js в приложении Create React. Как мы можем запускать только наши тестовые примеры HOC?

npm имеет параметр —-, который передает все аргументы после -- непосредственно сценарию.

Ниже приведены некоторые справочные сообщения:

$ npm test -- --help
Usage: test.js [--config=<pathToConfigFile>] [TestPathPattern]
Options:
  --help, -h                    Show help                          
  --version, -v                 Print the version and exit             
  --collectCoverage             Alias for --coverage.                  
  --collectCoverageFrom         A glob pattern relative to <rootDir> matching the files that coverage info needs to be collected from.
  --coverage                    Indicates that test coverage information should be collected and reported in the output.                                                                                    
  --testMatch                   The glob patterns Jest uses to detect test files.  
  --updateSnapshot, -u          Use this flag to re-record snapshots.

Затем следующая команда запустит все тесты HOC с соглашением об именах with*.test.js:

npm test -- --testMatch="<rootDir>/src/with*.test.js" --collectCoverage --collectCoverageFrom="src/with*.js"

Выполнение команды дает следующий результат. Мы рады видеть, что withColor.js был протестирован на 100% покрытие операторов, ветвей, функций и строк.

Тесты и покрытие для withFontStyle

Перейдем к другому HOC, withFontStyle. Это оболочка для настройки стиля шрифта для базового компонента:

Запустив тестовую команду, мы обнаруживаем, что withFontStyle.js имеет покрытие 0%. В нем четко указано, что приведенный выше код необходимо протестировать на третьей, четвертой и пятой строках.

Мы создаем упаковываемый компонент, который может отображать стиль шрифта: <div>Test Font Style</div>. Этот компонент используется для генерации withFontStyle HOC в шестой строке следующего тестового кода.

Другой компонент создается в строке 33. Этот компонент заключен в оболочку как withColor, так и withFontStyle:

Вот сгенерированные снимки: один для withFontStyle тестов, а другой - для тестирования комбинации withColor и withFontStyle:

Теперь у нас есть 100% покрытие для withFontStyle.js:

Тесты и покрытия для withMultipleValue

withMultipleValue написано несколько иначе. Вместо добавления оболочки div он изменяет свойства базового компонента:

Вот тестовые примеры:

Это сгенерированный снимок:

Запускаем тестовую команду и получаем следующий результат:

В нем говорится, что покрытие оператора 75%. Строка 11 из withMultipleValue.js не проверялась.

Итак, мы добавляем тестовые примеры в строки 27-40, чтобы вызвать обратный вызов onClick:

Мы снова запускаем тесты - вот отчет о покрытии:

Покрытие выписки составляет 100%, но филиалы покрываются не полностью.

Шестая строка в withMultipleValue.js - это условный (тернарный) оператор Number(props.value) ? props.value * factor : factor. Мы проверили условие truthy, но не условие falsy. Затем решение добавляет тестовый пример ниже в строках 20-25 без начального значения.

Теперь мы достигаем 100% покрытия всего:

Заключение

Мы использовали примеры HOC, чтобы проиллюстрировать, как писать тестовые примеры для HOC. Попутно мы также показали, как улучшить тестовое покрытие.

В реальном мире дела обстоят сложнее. Есть асинхронный код, недетерминированные последовательности выполнения, сторонние библиотеки и так далее. Достичь 100% охвата может быть невозможно, и охват 70% - 80% является разумной целью, хотя стоит стремиться к высокому уровню. Обычно это дает больше эффекта на последних 10-20% покрытиях.

Спасибо за прочтение. Я надеюсь, что это было полезно. Вы можете увидеть другие мои публикации в Medium здесь.