Автор оригинала: FreeCodeCamp Community Member.
Григори Бивер
Помощники и системы, чтобы сделать тестирование проще
Эта статья, которую я хотел бы найти, прежде чем я начал кодировать, используя всю фантазию реагирования.
В настоящее время в настоящее время работаю над комплексным офлайн-первым в конечном итоге приложение для планирования для летней музыкальной программы, чтобы заменить приложение MAC, написанное на объективном C много лет назад.
Приложение использует:
- Node.js Backend в Экспресс , с данными, хранящимися в Couchdb с Pouchdb В браузере, чтобы сохранить состояние между сеансами и управлять репликацией и конфликтами, а Реагировать с Redux На интерфейсе Redux-Saga управлять асинхронными мероприятиями, а для того, чтобы его подняться, капли тареться и бросить веселье с React-DND Отказ Это также приложение для тестирования, с 100% тестовым покрытием и в настоящее время соотношение 591 строк исходного кода до 7040 строк тестового кода.
Уроки, которые я узнал о том, чтобы избежать хрупких испытаний, чрезмерно зависимых тестов и облегчить тестирование всего одну вещь в одном тесте в этой статье.
Первые вещи в первую очередь: эта статья предполагает, что вы будете транспилировать ES6, используя Бабел или используя его непосредственно в кровотеченных краевых браузерах. Если вам нужно узнать об этом, есть много, много отличных ресурсов о том, как настроить Babel с WebPack или другие бабки для обслуживания вашего приложения. Эта статья Только Сосредоточется на том, как проверить вещи, как только ваша среда будет работать.
TL; доктор
Проверьте источник в https://github.com/cellog/testheelper
Но вы собираетесь захотеть прочитать это!
Почему эти вещи даже имеют значение?
Время историй! Я начал кодировать много лет назад, и увидел много тенденций и уйти. Объектно-ориентированный уголов из 80-х и 90-х годов революционизировал разделение кода, но привел к неизменяемому коду. Когда я изучал компьютерную науку (кратко) в начале 90-х годов, это было немного похоже на дикий запад. Они дали нам проблемы, и мы взломали, пока она не сработала. По большей части. Не было никакого способа проверить систему, за исключением запуска вашей программы и сравнивая вывод к ожидаемому выводу в виде одного монолитного кластера … ClusterFantasy. Кластер. Вы получаете идею.
В конце 90-х годов экстремальное программирование стало вещь, и вдруг появились тестовые рамки для использования. Быстро вперед почти 20 лет, и у нас есть зрелые, расширяемые и быстрые рамки с истинной изоляцией кода, поэтому мы можем проверить без побочных эффектов и языков, которые делают это легким, таким как наш друг JavaScript.
Я потратил значительное количество усилий в течение многих лет, экспериментирующих с разными стратегиями развития. В большинстве случаев я спроектировал код, а затем написал тесты после того, как я уверен, что дизайн был достаточно звуком, чтобы начать эту работу. Это было в порядке, за исключением случаев, когда это не было, а когда это не было, это была катастрофа. Я бы обнаружил, что код был на самом деле непростой.
Отличный пример – это веб-сайт, который я кодировал, используя Метеор Отказ Метеор был потрясающим, и позволил мне пойти от 0 до 60 с рабочим, сложным веб-сайтом примерно через месяц. Это было так просто, тесты даже не казались необходимыми. Тем не менее, я столкнулся с тонким жуком, с тем, как монподб был структурирован, и теперь нашел 2 или 3 других, что я буквально не могу исправить без переписывания с нуля. Когда Meteor ввел тестирование, он был специфичен для метеора, и не мог легко запустить тесты в нескольких браузерах, и вообще не поддерживает Wallaby без гигантского монолита Wallaby.js, которые нуждаются в своих собственных монтажных тестах Убедитесь, что это работает. Я буквально проснулся с кошмарами, пока я пытался решить эту проблему.
Таким образом, для этого проекта я решил написать тесты с самого начала, экспериментируя с тестируемым дизайном. То, что я нашел, это то, что писать тесты сначала заставляют дизайн изменить с самого начала, и мой код стал проще. Я начал развивать интуитивное подозрение, когда код стал слишком сложным, и начал стирать целые полосы кода, когда тестирование стало трудным или сложным в любом случае, потом нахожу гораздо более элегантные решения в половине времени после начала с нуля. Вот улов: темп развития составляет около 4 раза медленнее, чем то, к чему я использовал раньше. Однако я не беспокоюсь о тонких ошибках, ползущихся. Я не беспокоюсь об общем дизайне, будучи ломким. Чувство уверенности волнует и освобождает меня, чтобы мечтать о решениях вместо того, чтобы вывести огни.
Кроме того, я часто рефакторию, поскольку я узнаю больше о системе, который я проектирую и обнаруживаю тонкие неверные предположения о том, как библиотеки и базу данных, которую я использую на самом деле работу или ваш выбор дизайна. Я нахожусь очень часто стиранием и реконструированным кодом очень часто. Потому что я стираю и двигаю вещи так часто, и линии кода моих тестов в 14 раз больше, чем строки фактического кода, чтобы развить на все, что напоминает разумный темп, тесты должны быть хирургически разработаны, чтобы избежать подрывая на любые маленькие изменения. Я узнал это тяжело.
Большинство моих ранних испытаний имели тонкие зависимости от выбора дизайна, который откровенно не имеет значения для этого теста. Я бы продвинулся, и скопируйте/вставляя изменения в 20 или более тестов, когда я бы рефорию. Поэтому я сел и посмотрел на способы удаления любых зависимостей из тестов, а также заведует систему, которую описывает эта статья.
Каждый тест только тестирует 1 вещь, как правило, просто одна строка кода, и никаких изменений в любую другую область тестируемой области компонента приведет к сбою теста, за исключением ошибок компиляции или других легко фиксируемых ошибок. Моя надежда заключается в том, что мои ошибки рано помогут вам избежать их. С учетом того, давайте погрузимся!
Начинать
Начнем с списка инструментов, которые мы будем использовать, и где их найти.
Вот список импорта, которые нам понадобится:
Мы будем использовать стандартные импорт из React, Redux, привязки между React и Redux, а также контекстом для реагирования и ее тестирования. Давайте поговорим о чайной ложке.
Чайная ложка Является ли блестящим созданием Jason Scrience, которое позволяет тестировать компоненты реагирования, как если бы они были HTML, используя интерфейс, подобный jQuery. Это позволяет тестировать, пройдены ли определенные свойства, легко запускающие события с данными издевания, а также легко устанавливать свойства или состояние реагирования. Это прекрасно. Иди прочитайте документы. Увидимся через 15 минут.
Строить тестовый помощник с нуля
Добро пожаловать обратно!
Следующим шагом является создание базового интерфейса тестирования компонентов. Что нам нужно сделать, сначала настройте код рендеринга компонентов. Я экспериментировал с неглубоким, так и глубоким рендерингом чайной ложки чайной ложки и пришел к выводу, что никогда не бывает никаких веских причин использовать мелководье.
Основной проблемой с мелким рендерингом заключается в том, что через неделю вы забыли, что вы использовали неглубокий рендеринг, когда вы не обрабатываете, и ваш тест не пробел никаких веских причин, заставляя вас тратить 15 минут, пытаясь выяснить, почему до тех пор, пока вы не осознаете Все, что вам нужно сделать, это включить глубокий рендеринг и пройдут тест.
Итак, мы начинаем с простой функции RenderComponent, которую мы будем использовать для рендеринга любого React Component, и оберните его в чайной ложке, чтобы мы могли проверить об этом.
Этот код принимает класс или функцию комментариев реагирования или функцию, и проходит в любых свойствах, указанных в реквизитах. Простой.
Далее нам нужно подключить Redux, чтобы мы могли обрабатывать состояние:
Теперь мы можем писать тесты, чтобы обеспечить использование свойств в наших компонентах:
Подробнее о том, как писать эффективные тесты позже. На данный момент давайте продолжим следующую проблему.
Вскоре вам нужно будет проверить изменение недвижимости. К сожалению, это трудно сделать, потому что рендеринг является асинхронным, а тесты синхронно по своей природе. К счастью, есть способ заставить рендеринг быть синхронно. Не собираясь слишком много подробно, используя компонент более высокого порядка, чтобы обернуть класс класса компонентов, и опоры настройки, используя локальное состояние RACT, заставит перезарядки, чтобы мы могли проверить для эффекта изменения свойства. Вот новый RenderComponent:
Далее нам нужно подумать о том, как проверить компоненты контейнера. По моему опыту, заманчиво попытаться проверить внутренний выходной доступ в HTML-вывод класса RACT, но это гораздо больше, чтобы проверить, что на самом деле делает контейнер. Классы контейнеров имеют 1 работу: преобразование состояния Redux в свойства компонента реагирования.
Используя чайную ложку, вы действительно можете проверить, что контейнеры предпринимают ломтик состояния и надежно создают имена компонентов и значений, которые ожидают внутренний реактивный компонент, без необходимости знать что-либо о внутренних условиях компонента реагирования внутри теста контейнера.
Наиболее заметное исключение с этим фактом является то, что нам также нужно проверить действия. Чтобы сделать это, лучше всего тестировать либо изменение состояния, которое ожидается при отправном действии, либо проверять, если действие было отправлено.
Чтобы проверить состояние, нам нужно получить доступ к состоянию после того, как действие срабатывает, и мы можем сделать это, используя метод gootstate () redux Store. Итак, нам нужно будет вернуть магазин, если это необходимо.
Наиболее разумным методом – проверять, было ли отправлено правильное действие. Для этого нам нужно будет создать промежуточное программное обеспечение redux, которая просто регистрирует все действия в массив, который затем может использоваться для проверки отправленных действий. Давайте модифицируем RenderComponent, чтобы сделать эти два сценария возможными:
Вопрос о том, как использовать эту более продвинутую функциональность, будет адресована во второй половине этой статьи, где я опишу, как использовать этот хелпер для записи эффективных и ограниченных тестов.
Последняя часть испытуемого помощника довольно проста, и просто добавляет поддержку для React-DND. Все, что нам нужно, это обернуть все внутри драгдропконтестика с тестовой бэкэндом:
Теперь мы можем получить доступ к менеджеру с драков и Backend с Dragbleable.getmanager ()
и Draggable.getManager (). GetBackend ()
Как задокументировано в DND-документах. Обратите внимание, что .Прототип
требуется для доступа к GetManager ().
На этом этапе мы готовы исследовать, как эффективно использовать этот тестовый помощник.
Написание отличных испытаний, используя помощника
Есть несколько ключевых принципов, которые сообщают, как я пишу тесты:
- Не повторяйте ничего
- Используйте умную котующую табличку
- тестовые свойства и действия отдельно
Вот пример протестированного компонента, который имеет как свойства, так и действия. Пример использует Синон Для проверки обратных вызовов:
Обратите внимание, что если вы хотите проверить изменение свойства, чтобы проверить метод жизненного цикла, такого как должен использовать Teaspoon реквизит () метод. То же самое относится и к Государство () для тестирования местных государственных изменений.
Испытание выше использует несколько объединяющих идей:
- Даже RenderComponent () абстрагируется в 2 новых методах, один для тестирования свойств (визуализации) и один для тестирования действий (Make).
- Указывается общий набор свойств по умолчанию, так что не будет никаких предупреждений на реагирование для любых тестов, что позволяет каждому тесту сосредоточиться на одном свойстве (удачно названо «универсальным».)
- Нет тестирования визуальных свойств/CSS/HTML непосредственно за пределы обеспечения того, чтобы основные леса присутствовали
- Тест фокусируется на обеспечении внешнего входа к компоненту правильно. Каждое свойство проверяется, и каждое действие проверяется.
- CSS/HTML используется только для определения местоположения места, где недвижимость расположена в виртуальном доме компонента.
Мы расширим эти идеи для тестирования подключенных контейнеров React-Redux Next.
Тестирование компонентов контейнера для подключенного redux
Самое главное, что компонент redux делает – это преобразует состояние в свойства и обратные вызовы в действия Redux. Использование созданного RenderComponent мы создали, мы можем легко проверить это:
Здесь мы можем исключительно тестировать исключительно, что наш соединительный контейнер преобразует состояние в недвижимости, которые мы ожидаем, и распределяет действия, которые мы ожидаем. В большинстве моих предыдущих тестов я бы проверил, чтобы убедиться, что действия модифицированы государством (второй метод в исследовательском тесте), но это фактически дублирует работу обеспечения того, чтобы ваши редукторы снижались. Таким образом, если вы восстанавливаете редуктор, вы должны обновить каждый тест для подключенного контейнера. Это может сделать рефакторинг медленнее.
Вместо этого проверка, на то, какие действия были отправлены полностью отделены от редуктора и просто проверяют контракт на подключенный компонент.
Есть недостатки для развязки, в том, что изменение редуктора может иметь несколько побочных эффектов в контейнерах. Если вы знаете об этом, то вы в порядке. В магазине мульти-разработчика или при разработке амнезии через несколько месяцев, вы можете захотеть иметь все, что связано с редуктором, когда изменение сделано.
Тестирование обработчика действий redux-Saga
Если вы хотите проверить генератор Redux-Saga, который очень тщательно документируется на сайте redux-Saga. Если вы обнаружите, что слишком запутаны, и хотите статью о том, как я это делаю (или почему я выбрал Redux-Saga), пожалуйста, ответьте в комментарии.
Одним из моделей, в которых я столкнулся в этом приложении, что требует Redux-Saga, превращает одно действие на несколько действий. Случайное применение для этого в моем приложении планирования – слушатель, который я написал для обновления экземпляра CouchDB, когда записи изменяются клиентом. Чтобы реализовать надлежащий обнаружение конфликтов, в то время как записи независимо обновляются онлайн, каждая запись должна иметь тот же идентификатор. Таким образом, уникальные идентификаторы генерируются на основе названий композиторов кусков, которые могут играть дети. Когда имя композитора обновляется, каждый экземпляр использования этого композитора также должен быть обновлен. Таким образом, одно действие порождает много новых действий. Из-за потенциала для пропущенных действий и непоследовательного состояния в базе данных я написал SAGA для прослушивания действий по модификации, а затем отправлять многие новые действия, чтобы внести необходимые изменения.
Таким образом, при нажатии кнопки «Сохранить», действие отправляется, что не обрабатывается каким-либо редуктором. Вместо этого он перехвачен сагой и преобразуется во многие отдельные действия, которые необходимы. Это также обновляет базу данных.
Это могло быть реализовано с промежуточным программным обеспечением, но Redux-Saga делает обработку всех асинхронных порций работы настолько простыми, она не имеет смысла повторно изобретать колесо, когда несколько строк кода могут сделать ту же работу и быть легче проверено. Как мы это проверим? Мы могли бы создать прослушиватель Mock Redux-Saga для действия в нашем испытательном помощнике, но как долго мы ждем, пока сага завершится до того, как мы проверим наше состояние, чтобы он был изменен? Как мы помешаем сагу на самом деле пытаться изменить базу данных? Наступает кошмар!
Короче говоря, в этом случае все, что нам нужно проверить, состоит в том, что подключенный компонент распределяется действие, которое будет перехвачено Redux-Saga. Отдельный тест может быть использован для проверки правильности самого саги. Как только это подтверждено, то мы можем быть уверены, что действие будет работать.
Таким образом, мы можем использовать промежуточное программное обеспечение журнала, которую мы создали в нашем тестовом хелпере, чтобы посмотреть, на самом деле отправляется действие, которое мы намереваемся отправить. Легкий!
Тестирование React-DND
React-DND нуждается в контексте перетаскивания и падения для работы без ошибок, даже если вы ничего не делаете с перетаскиванием в тесте. Если вы завернули любой из ваших компонентов, вы все равно хотите иметь возможность проверить основные функциональные возможности этого компонента, и наш тестовый помощник делает это возможным. Вы можете проверить основные функциональные возможности, используя наш тестовый помощник и игнорируете перетаскивание, затем проверьте перетаскивание в отдельном тесте, используя методы, выложенные в документации для реагирования, если это необходимо. Очень просто!
Единственную голчу, которую я нашел, так это то, что он не интуитивно понятен, как насмешлиц перетаскивать и падать, и документация находится в лучшем случае. Вот образец теста из моего настоящего проекта, показывающий, как проверить взаимодействие перетаскивания. Обратите внимание, что рассматриваемые компоненты глупые компоненты, и свойство книга
и ясно
являются обратными обратными вызовами, поставляемыми на Credux-Contact Conticater. Я включаю контейнер, даже если эти тесты на самом деле не тестируются, чтобы сделать это понятным. Также обратите внимание на создание функций помощника для извлечения источника источника и целенаправления от компонента напрямую, определенного как Источник
и цель
Функции в slot.test.js.
Инструменты, которые я использую, которые сохранили мою службу программирования
Если вы не вложили в Wallaby.js или веб-штуру, вы пропустите. Имея мгновенные результаты теста, мгновенный тестовый охват видимой линии по линии, а также ваша непрерывная интеграция с кармой – это боготворение. Я использую карму на RooseStack, чтобы убедиться, что код не разрывается в браузерах мобильных и настольных компьютеров, и Wallaby быстро убедитесь, что мой код работает и покрыт домиком.
Вот образец Wallaby.js, который я использую для моего проекта, при поддержке модулей CSS в тестах:
Кроме того, если вы не используете React-StoreBook , Вы пропускаете. Это лучший способ развить свой визуальный вид приложения с некоторой гарантией, оно будет работать. Он систематизирует ручное тестирование, последний элемент любого успешного приложения, а недавние версии могут даже автоматизировать это тестирование, хотя я не использовал это лично.
Заключение
Есть много разных способов тестирования. Если вы разрабатываете сложное приложение в React-redux, вы захотите забрать, как отсоединить ваши компоненты, чтобы их можно было легко проверить. К счастью, с этим простым испытательным помощником и принципами для тестового дизайна тестирование легко, и вы можете рефакторировать с ограниченными побочными эффектами на несвязанные тесты, делая разработку быстрого и изменения.
Счастливое кодирование! Пожалуйста, оставьте комментарий, если у вас есть другие системы, которые я не упомянул, я всегда ищу новые идеи. Кроме того, если что-то я сказал, неясно или неполно, пожалуйста, спросите, и я рад пытаться уточнить.
Нажмите на эту кнопку «Это красивое сердце», если вам нравится статью!