Автор оригинала: FreeCodeCamp Community Member.
Рональдом Рей
Удерживая его каркасным агностическим
Когда дело доходит до общих взаимодействий между пользователем и веб-приложением, обычно это довольно просто для моделирования этих действий в среде тестирования, чтобы утвердить правильную функциональность приложения. Я имею в виду такие вещи, как кнопки нажатия, заполняя формы, навигационные маршруты … обычные вещи. Однако в Интернете есть некоторые менее распространенные впечатления, которые намного сложнее тестировать. Одним из них является функциональность перетаскивания.
Это частично из-за того, насколько сломаны и непоследовательны API HTML5 Drag и Drop. Это привело много авторов библиотеки, чтобы выпить свои уникальные подходы к проблеме, часто сильно отличаются друг от друга. Это означает, что реализация такой функциональности в вашем приложении может быть весьма сложным, и для неиспользованного разработчика это может быть еще более сложным написать правильные автоматизированные тесты для него.
Для моего отчаяния приложение, на котором я работаю в данный момент, на момент полного времени имеет много связанных с перетаскивающими функциями. К счастью, это было довольно легко благодаря богатой экосистеме библиотек библиотек, которые уже решали эту проблему, и, кажется, это прибит.
Тем не менее, автоматически тестирование этих функций может быть нетривиальным, и я хотел бы поделиться некоторыми из уроков, которые я узнал. Я использую реагирование, и многие фрагменты и образцы будут реагировать ориентироваться. Но на самом деле те же концепции могут быть применены к любому стеке, которая является красотой все это.
Первоначальный подход
ОК, настолько, скажем, мне нужно построить таблицу, которая имеет перетаскивание строк, выглядящее что-то подобное (кстати, не слишком отвлекайтесь на реализацию):
Как вы можете видеть, я использую классическую React-DND
Библиотека настоящего знаменитого Дэна Абрамова. Функция сделана, так как мы пойдем о тестировании его на данный момент? Если вы перейдете к документации, вы найдете аккуратный раздел « тестирование», который, вероятно, заставит ваши глаза сиять Отказ
Есть предложение о использовании «тестовой бэки». В основном вы оберните оформленный компонент, используя эту бэкэнд вместо обычного Backend HTML5. Это позволит вам проверить его вне среды браузера, то есть без доступа к DOM.
Таким образом, в этом последнем предложении предыдущего абзаца я бросил много странных концепций у вас: украшенный компонент, Backend, тестирование Backend, Backend HTML5 … что? Это все внутренние основные концепции React-DND
и DND-CORE
Все связаны с тем, как он работает под капотом. Светая руководство по себе признает это, и утверждает, что это наименее задокументированная часть библиотеки из-за этого.
Значит ли это, что я должен быть грамотно знаком с тем, как эта библиотека в частности работает, чтобы иметь возможность тестировать ее? Ну, для меня, это то, что предлагает документация. Это сложно, потому что он может вводить в заблуждение нерешенным разработчикам.
Таким образом, у меня есть несколько решений об их предложенном подходе:
- Чтобы проверить эту функцию, я должен быть знаком с тем, как эта библиотека в частности, работает внутри и ее детали реализации.
- Чтобы проверить эту функцию, я также должен быть знаком с тем, как работает «тестирование Backend», что является то, что я не должен быть знакомым, в первую очередь, чтобы создать функциональность перетаскивания, используя эту библиотеку. Это означает, что у меня есть еще один набор документации, чтобы потреблять, и целое другое измерение проблем, которые я мог бы запустить, не обязательно совместно используются с помощью обычного HTML5 Backenc, я бы использовал для моего приложения.
- Тот факт, что у меня есть всеобъемлющий пропускной тестовый набор, используя этот подход, не обязательно гарантирует мне, что он на самом деле работает, как я ожидаю, что от точки зрения пользователя. Подумайте об этом: в моих тестах и в дикой природе функциональность будет работать с совершенно другими внутренними. И, несмотря на лучшие намерения сопровождающих, этот подход не обязательно не обязательно масштабируется до остальной части экосистемы JS, и может дать вам ложное чувство безопасности.
- Если я когда-нибудь решил изменить подход к функциональности и вместо этого использовать другую библиотеку, или напишите ее, все мои тесты внезапно станут устареть, и мне придется переписать их снова.
Теперь не поймите меня неправильно – это здорово, что они ушли на такие длины, чтобы создать «тестирование Backend», чтобы функциональные возможности могли быть проверены без DOM. Это, безусловно, полезно и имеет свое место. Но это не то, что я бы порекомендовал из-за проблем, которые я только что перечислил.
Что я после того, что следующее:
- Набор тестов, которые гарантируют на максимальную степень, что функциональность работает, как ожидалось (невозможно достичь 100% уверенности без сквозных испытаний, а не то, на данный момент я на данный момент). Это означает, что я хочу утверждать точное поведение функциональности с точки зрения пользователя в моих тестах.
- Я могу поменять или изменить реализацию функции (которая включает в себя любую библиотеку, используемую внизу) в любое время с минимальным воздействием на тесты.
- Я не должен быть знаком с реализацией функциональности для записи тестов.
- Мне нужно только использовать свои уже существующие и знакомые знания веб и веб-API в целом, чтобы написать эти тесты.
Движение вперед
Что бы я порекомендовал тогда? Ну, просто эмулируйте в ваших тестах, что пользователь будет делать при использовании приложения. По сути, я защищаю, что вы пишете полноценные тесты интеграции для этой функции вместо единичных/изолированных тестов, таких как документация предлагает.
В наши дни у нас есть jsdom Что позволяет нам выстрелить в память о среде браузера с высокой верностью, без использования фактического браузера. Честно jsdom
Настало настолько хорошими годы, которые я почти не вижу причин писать какие-либо тесты веб-приложений, которые пытаются не использовать или получить доступ к DOM. Практически все, что вы можете сделать в консоли разработчика браузера, можно сделать в памяти с jsdom
, с некоторыми исключениями и предостережениями, конечно, которые мы увидим в ближайшее время.
Отказ от ответственности: Я не говорю, что вы никогда не должны писать модульные тесты или тесты таким образом. Конечно, каждый сценарий и проблема отличается. Поместите свою мышную крышку и решите, что лучше всего в каждом конкретном случае!
Хорошо, как мы это делаем? Просто, просто задайте себе вопрос: какой пользователь сделает с моим приложением, чтобы использовать функцию перетаскивания, а как будет вести браузер, когда это произойдет? Когда у вас есть этот ответ, просто код в тесте, используя Regular API для DOM, доступен для вас доступен jsdom
! Давайте посмотрим, как тест на перетаскивание пониженного действия будет искать наш конкретный пример, используя jest
:
const getTableCells = () => Array.from(mountNode.querySelectorAll("tr td:nth-of-type(1)")); const createBubbledEvent = (type, props = {}) => { const event = new Event(type, { bubbles: true }); Object.assign(event, props); return event; }; const tableCells = getTableCells(); const startingNode = tableCells[0]; const endingNode = tableCells[2]; startingNode.dispatchEvent( createBubbledEvent("dragstart", { clientX: 0, clientY: 0 }) ); endingNode.dispatchEvent( createBubbledEvent("drop", { clientX: 0, clientY: 1 }) ); expect(getTableCells().map(cell => cell.textContent)).toEqual([ "Bob", "Clark", "Alice", ]);
Там нет абсолютно ничего React-DND
Или даже связаны с реагированием в этом фрагменте, и даже не используют тест на реагирование имитации. Это означает, что я мог бы вообще изменить мою библиотеку/рамку для пользовательского интерфейса для чего-то вроде угловой (черт возьми, даже позвоночнику?) И этот тест все еще будет иметь смысл и работать, как ожидалось.
Только в одиночестве достаточно, чтобы правильно проверить, что подмножество функциональности, однако, есть много других событий, которые происходят в реальном браузере ( Mousedown
, MouseMove
, перетягиваться
и т. Д.) Просто не произошло играть роль в нашей реализации. Это означает, что с другой реализацией возможно, что тест потребует несколько вещей, добавленных или удаленных.
(Кстати, симулировать использование открыто обескуражено экспертами отрасли. Кроме того, если вы потратили более 5 минут в любом из проблем со мероприятием Enzyme, связанные с темистовыми номерами, вы увидите то же самое мнение со стороны самих авторов. Даже были комментарии о его удалении в предстоящих версиях ).
Выглядит круто. Желаю этого не полагаться на Testutils.simulate и просто смоделировали фактические мероприятия DOM. К сожалению, это не то, что делает Testutils.simulate?
Единственные несколько вещей, которые не обязательно очевидны:
- События должны быть пузыреми, что не по умолчанию, когда мы создаем их вручную с конструктором – поэтому нам нужно явно установить его. Это связано с тем, как работает система делегирования событий RECAGE. Вы можете подумать, что это деталь реализации, но это не обязательно так. События пузыряют в браузере при запуске фактическим реальным взаимодействием в любом случае.
- Нам нужно установить
ClientX
иклиенты
Свойства события, потому что они используются для определения направления перетаскивания. Опять же, с другими реализацией могут быть другие свойства на события или другие методы, которые вам придется исправлять, чтобы сделать его работать (например.getBoundingClientRect ()
). Например, если реализация использовала что-то вроде.offsetx
,.movementx
,.top
или любой другой размер, положение и свойства, связанные с движением.
И это об этом. Мы обратились к всему моим вопросам и достигли всех целей, которые мы изложили для себя. С еще несколькими линиями кода можно пройти тестовое покрытие этого репо на 100% довольно легко.
Последние мысли
Не стесняйтесь исследовать весь тестовый люкс здесь Отказ Несколько дополнительных вещей, чтобы получить покрытие до 100%, поэтому убедитесь, что проверьте это. Обратите внимание, что я написал все в одном тесте только ради краткости.
Что-то еще, что я хотел бы упомянуть. Новый разработчик может прийти в код для тестов и точно знать, что происходит. Представьте, что тесты используют React-DND
Ориентированные тесты, используя все виды внутренних концепций и деталей … это будет огромная стена на их лице и может представлять существенное препятствие для их способности своевременно внести свой вклад в тесты. В этот момент они должны будут прочитать React-DND
Документация, DND-CORE
и React-Testing-Backend
Исходный код … Yikes!
Я хочу оставить вас с этим постом блога Софи Альпертом, менеджером команды React Core в Facebook, описывая о том, как они могут успешно отправить API-совместимую к полному перезаписи в режиме реагирования от версии 15 до версии 16, без единого разрыва. Alert Spoiler: Комплексные испытательные апартаменты утверждали функциональность библиотеки с точки зрения аутсайдера вместо того, чтобы сосредоточиться на деталях реализации или изолированных модульных тестах.
Что на самом деле забавно, в том, что по состоянию на июль 2018 года все фрагменты от официальной документации по реагированию использовали устаревшую версию 0,14, и оказалось, что они работали точно так же в версии 16.x. Это просто идет, чтобы показать, какая отличная работа, которую они сделали поддержание обратной совместимости, и это было бы невозможно без этих хорошо написанных и целенаправленных тестов!
Rection 16: Просмотр в API-совместимый переписывание нашей библиотеки интерфейса интерфейса Опубликовано на веб-реакцию 16: Просмотр API-совместимый перезапись нашей библиотеки интернет-пользовательского интерфейса React делает его простым … code.fb.com.
Только что получил отчет о том, что кодовые работы в официальном руководстве на веб-сайте RACT использовали двухлетнюю версию реагирования (0,14). Не могу решить, следует ли я смущать, что я забыл их обновить, или гордиться тем, что все они работают с последними реакцией 16 с нулевыми изменениями.
Бонус: несколько советов о том, как выяснить, как эмулировать поведение браузера
Если есть какая-то другая функциональность, которую вы хотите проверить таким образом, но вы не уверены, насколько ведет себя браузер при совершении этого, я предлагаю вам посмотреть Google Chrome’s Monitorevents
API Отказ Это безумно полезно в этих сценариях, особенно когда вы не уверены, что происходит. Я сам использовал это так, как это исследовать форму событий, выпущенных при перетаскивании:
monitorEvents(document.body, [ 'mousedown', 'mousemove', 'dragstart', 'dragenter', 'dragover', 'drop', 'dragend', 'mouseup', // … ])
В общем, было бы чрезвычайно выгодно, если вы просто вытесните консоль разработчика браузера и начните играть с системой событий, пока не почувствуете себя уверенно, вы знаете, как это работает. Создание элементов, триггерные события, переместите их вокруг, прикрепите их к DOM, отсоедините их и т. Д… Все, что нужно! Инвестируя один или несколько часов с этим будет служить вам на всю оставшуюся вашу карьеру в качестве веб-разработчика. Довольно сладкое дело в моих глазах:)