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

Если вам не нравится тестировать свой продукт, скорее всего, ваши клиенты тоже не захотят его тестировать. - Кузнечик

Есть причина, по которой модульные тесты составляют основу Треугольника тестирования. Идея здесь в том, что нужно писать больше тестов в нижней части треугольника и все меньше и меньше тестов, когда мы продвигаемся вверх по треугольнику. Так что больше модульных тестов, чем интеграционных и т. Д.

Что именно мы проводим модульное тестирование?

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

Какие фреймворки мы используем?

Эти тесты написаны с использованием тестовых фреймворков, и в этой статье мы будем использовать Jest, фреймворк для тестирования JavaScript от Facebook, вместе с Enzyme, утилиту Airbnb для тестирования React.

Настроить Jest и Enzyme

Давайте начнем с нуля и создадим новое приложение с поддержкой React. Обратитесь к Начало работы - React Native для инструкций по установке.

Jest поставляется прямо из коробки, так что позвольте установить Enzyme. Обратитесь к Инструкции по установке фермента для получения дополнительной информации.

Установите зависимости от энзимов, открыв сеанс терминала в корневом каталоге проекта и выполнив в нем следующую команду. С этого момента я буду называть эту папку rootDir.

npm i — save-dev enzyme enzyme-adapter-react-16 react-dom

Создайте jest.config.json файл в rootDir.

Обратитесь к Руководству по настройке Jest для получения дополнительной информации о доступных параметрах.

Создайте папку с именем jest внутри rootDir, а затем создайте setup.js файл в rootDir / jest / папку.

Теперь мы готовы начать модульное тестирование в React Native с Jest и Enzyme. 😎 🎊

Снимок во времени 📸

Что такое тестирование снимков?

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

Хороший снимок на мгновение останавливает бегство - Юдора Велти

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

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

Основы тестирования снимков

Давайте настроим базовый компонент button, чтобы мы могли протестировать его с помощью снимков.

Создайте файл Button.js в папке rootDir / src.

Теперь давайте создадим тестовый (иногда называемый spec) файл. Создайте Button.test.js

Вы также можете назвать этот файл Button. spec .js. Jest примет оба расширения и добавит расширение файла по мере необходимости для автоматически сгенерированных файлов, таких как снимки.

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

Запуск тестов

Пришло время выполнить тест. Мы делаем это, используя следующее.

npm run test

Поскольку мы запускаем этот тест снимка впервые, Jest создаст для нас файл снимка внутри папки __snapshots__.

Что происходит, когда что-то меняется?

Полезность снимков вступает в игру, когда вы (или кто-то другой) меняете презентационный аспект этого компонента. В качестве примера попробуйте изменить fontSize на другое значение, кроме 16 в Button.js, и снова запустите тесты. Вы увидите следующую ошибку.

Received value does not match stored snapshot

Это означает, что мы изменили способ визуализации этого компонента. Если это сделано намеренно, мы можем обновить снимок, передав флаг -u в npm run test вот так

npm run test -- -u

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

Я изменил Button.js на

  1. Компонент на основе классов
  2. Пользовательская функция вызывается при касании onPress
  3. Изменить цвет кнопки в зависимости от «основного» свойства

Давайте протестируем этого щенка, запустив тесты и обновив снимки (это npm run test -- -u, если вы забыли)

Отчет о покрытии

Когда мы запускаем тесты, jest создает для нас хороший отчет о покрытии. Чтобы посмотреть на него, перейдите к rootDir / охват / lcov-report / index.html.

Нажав на Button.js, вы увидите покрытие визуально. Из этого мы можем сделать вывод, какие операторы / ветви не охвачены.

В строке 24 появляется ветвь не покрыта, потому что мы устанавливаем значение по умолчанию для primary props равным true в компоненте Button. А в Button.test.js мы не передаем свойство для primary, поэтому используется значение по умолчанию.

const component = shallow(<Button label="test label"/>)

Измените Button.test.js, чтобы исправить это.

Теперь осталось протестировать onPressHandler функцию. Но для этого нужно говорить о издевательстве 😮

Не смейся надо мной 🐒

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

Мок-функции также известны как «шпионы», потому что они позволяют вам следить за поведением функции, которая косвенно вызывается другим кодом, а не просто проверять вывод.

Давайте сосредоточимся на двух способах, которыми Jest помогает нам с издевательством

  • jest.fn() - фиктивная функция
  • jest.mock() - макет модуля

Мокающие функции с jest.fn ()

jest.fn() предоставляет способы захвата вызовов, установки возвращаемых значений и изменения реализации функции. Обратитесь к Jest mock function api для получения дополнительной информации.

Позвольте пользователю jest.fn() проверить, вызывается ли onPress внутри onPressHandler()

  1. Имитационная функция с экземпляром функции шутки.
  2. Передача фиктивной функции в качестве опоры (как onPress). После onPress мы ожидаем, что будет вызвана фиктивная функция.
  3. Вызов onPressHandler () вручную
  4. Проверка того, вызывается ли фиктивная функция и сколько раз

Мокинг модулей с помощью jest.mock ()

jest.mock() - это решение для имитации модулей от Jest.

Давайте воспользуемся им, чтобы узнать, звонят ли Linking.openURL() или нет и при каких обстоятельствах.

  1. Установите функцию модуля openURL на jest.fn
  2. Подготовка многократно используемого мелкого отрисованного экземпляра, чтобы мы не повторялись, пытаясь создать тот же мелкий экземпляр с теми же реквизитами.
  3. mockOpenURL должен вызываться, так как мы передали опору 'url'
  4. mockOpenURL НЕ должен называться, поскольку мы НЕ передали опору 'url'

Анатомия модульного теста

Есть несколько разных способов структурировать модульный тест. Наиболее распространенным шаблоном является AAA (Arrange Act Assert).

Идея состоит в том, чтобы разделить ваш тест на указанные три части, чтобы было легче рассуждать о тесте.

Некоторые хорошие практики 🏃

В первую очередь важно писать тестируемый код.

Модульное тестирование следует начинать до того, как мы напишем какие-либо тесты. Написание тестируемого кода так же (если не больше) важно, как написание самих модульных тестов.

Модульное тестирование только одного фрагмента кода / функции за раз.

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

Скорее, проведите модульное тестирование этих разных модулей самостоятельно. Проверить функцию, которая вызывает api, и протестировать при разрешении / отклонении того состояния, которое она устанавливает. Затем в другом тесте проверьте это состояние, как компонент отрисовывается.

Каков выход при определенных входных данных?

Размышление в этих терминах значительно упростит рассуждение о том, что и как проводить модульное тестирование.

Шаблон AAA (Arrange, Act, Assert)

Это также помогает думать в терминах шаблона AAA (Arrange, Act, Assert), когда вы начинаете писать тест, поскольку это дает четкое разделение согласованности в структуре ваших тестов.

Заворачивать

Это несколько основных способов начать модульное тестирование вашей кодовой базы React Native с помощью Jest и Enzyme. У них обоих есть отличная документация, поэтому нет причин, по которым вы больше не должны тестировать свою кодовую базу. ⭐️ 🌟 ✨

Спасибо, что уделили время чтению этой истории !. Если вам понравилось и / или вы нашли это полезным, оставьте 👏. Если нет, оставьте комментарий и дайте мне знать, что я могу улучшить в следующем. Удачного модульного тестирования.

Изменить, 14 декабря 2018 г.: устранена проблема в разделе Настроить Jest and Enzyme.