Изменить, апрель 2022 г.: Никогда не используйте Enzyme для тестирования приложений React Native

Написание тестов требует от вас мышления, которое немного отличается от написания кода, и это может не прийти к некоторым инженерам быстро, но не ко мне.
Добавьте к этому тот факт, что использование Enzyme для тестирования React Native проект может показаться немного неуклюжим, учитывая, что Enzyme был создан для тестирования React в Интернете.

В любом случае, Enzyme по-прежнему является популярным решением для написания модульных, компонентных и интеграционных тестов для React Native, поэтому я подумал, что стоит потратить время на то, чтобы узнать, как это делается. Вот несколько идей, которые могли бы улучшить мой опыт, когда я впервые начал учиться тестировать приложения React Native с помощью Enzyme. Обратите внимание, что эти советы применимы только к поверхностному рендерингу, я не буду говорить о Enzyme mount в этой статье.

Вспомогательные функции — ваши друзья

Код для поиска нужного узла в вашем компоненте может показаться немного многословным.

Вместо этого может помочь обернуть эти утомительные запросы во вспомогательные функции, чтобы вам не приходилось каждый раз вводить много текста при их использовании:

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

В веб-проектах вы можете использовать wrapper.simulate(“click”) и т. д. для имитации взаимодействия с пользователем. Это не будет работать в React Native, поэтому вместо этого мы используем реквизиты обработчиков событий компонентов. Вот несколько примеров для различных типов входных компонентов:

Считается плохой практикой проверять значения состояния компонента.

В сети или даже в кодовых базах, с которыми вы работали, вы можете увидеть такие тесты:

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

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

Функциональные компоненты не имеют экземпляров (и это нормально!)

Поклонники функциональных компонентов React могут быть встревожены, узнав, что для функциональных компонентов доступно меньше ShallowWrapper API Enzyme, чем для компонентов класса. Обертка, созданная из функционального компонента, не имеет, например, метода instance, который некоторые люди используют в своих тестах для прямого вызова методов компонента класса, а затем проверяют, имел ли место ожидаемый побочный эффект. Например:

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

Используйте метод отладки оболочки, чтобы увидеть, что видит Enzyme

Сначала я обнаружил, что концепция Enzyme о ShallowWrapper трудно обернуть в моей голове 😅. Достаточно легко понять, что обертка, возвращенная из shallow(), содержит представление всего вашего компонента, но последующие запросы к этой оболочке с такими методами, как find() и findWhere(), также возвращают ShallowWrapper, что для меня было чуть менее интуитивным.

Вместо того, чтобы обращаться с этими оболочками как с черными ящиками для слепых запросов, вы можете использовать метод debug(), чтобы увидеть визуальное представление объекта. Вот краткий пример:

То, что вы видите в выводе выше, вероятно, вас не удивит. Он выглядит почти идентично JSX-коду фактического компонента. Вы можете подумать: «Круто, оболочка — это просто представление дерева компонентов моего приложения». В данном случае это так, но все становится интереснее, когда мы смотрим на обёртку, возвращаемую запросом .find():

В этом примере textWrapper.debug() дает нам больше того, что вы могли бы представить в виде списка дочерних компонентов, соответствующих нашему запросу find(). На самом деле API-интерфейс оболочки дает нам at()method для запроса с использованием индекса компонента внутри оболочки:

С оболочкой Enzyme становится намного проще работать, когда вы начинаете думать о ней как о списке или наборе компонентов, а не как о дереве компонентов. Взгляните на ShallowWrapper документацию API для получения списка всех доступных методов.