Рубрики
Без рубрики

Как писать лучшие тесты для операций перетаскивания в браузере

Ronald Rey Как писать лучшие тесты для операций перетаскивания в браустрево, сохранение IT Framework-agnosticphoto от Ash Edmonds на UnsplashWhen, речь идет об общих взаимодействиях между пользователем и веб-приложением, обычно это довольно просто, чтобы имитировать эти действия в среда тестирования, чтобы утверждать

Автор оригинала: FreeCodeCamp Community Member.

Рональдом Рей

Удерживая его каркасным агностическим

Когда дело доходит до общих взаимодействий между пользователем и веб-приложением, обычно это довольно просто для моделирования этих действий в среде тестирования, чтобы утвердить правильную функциональность приложения. Я имею в виду такие вещи, как кнопки нажатия, заполняя формы, навигационные маршруты … обычные вещи. Однако в Интернете есть некоторые менее распространенные впечатления, которые намного сложнее тестировать. Одним из них является функциональность перетаскивания.

Это частично из-за того, насколько сломаны и непоследовательны API HTML5 Drag и Drop. Это привело много авторов библиотеки, чтобы выпить свои уникальные подходы к проблеме, часто сильно отличаются друг от друга. Это означает, что реализация такой функциональности в вашем приложении может быть весьма сложным, и для неиспользованного разработчика это может быть еще более сложным написать правильные автоматизированные тесты для него.

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

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

Первоначальный подход

ОК, настолько, скажем, мне нужно построить таблицу, которая имеет перетаскивание строк, выглядящее что-то подобное (кстати, не слишком отвлекайтесь на реализацию):

Как вы можете видеть, я использую классическую React-DND Библиотека настоящего знаменитого Дэна Абрамова. Функция сделана, так как мы пойдем о тестировании его на данный момент? Если вы перейдете к документации, вы найдете аккуратный раздел « тестирование», который, вероятно, заставит ваши глаза сиять Отказ

Есть предложение о использовании «тестовой бэки». В основном вы оберните оформленный компонент, используя эту бэкэнд вместо обычного Backend HTML5. Это позволит вам проверить его вне среды браузера, то есть без доступа к DOM.

Таким образом, в этом последнем предложении предыдущего абзаца я бросил много странных концепций у вас: украшенный компонент, Backend, тестирование Backend, Backend HTML5 … что? Это все внутренние основные концепции React-DND и DND-CORE Все связаны с тем, как он работает под капотом. Светая руководство по себе признает это, и утверждает, что это наименее задокументированная часть библиотеки из-за этого.

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

Таким образом, у меня есть несколько решений об их предложенном подходе:

  1. Чтобы проверить эту функцию, я должен быть знаком с тем, как эта библиотека в частности, работает внутри и ее детали реализации.
  2. Чтобы проверить эту функцию, я также должен быть знаком с тем, как работает «тестирование Backend», что является то, что я не должен быть знакомым, в первую очередь, чтобы создать функциональность перетаскивания, используя эту библиотеку. Это означает, что у меня есть еще один набор документации, чтобы потреблять, и целое другое измерение проблем, которые я мог бы запустить, не обязательно совместно используются с помощью обычного HTML5 Backenc, я бы использовал для моего приложения.
  3. Тот факт, что у меня есть всеобъемлющий пропускной тестовый набор, используя этот подход, не обязательно гарантирует мне, что он на самом деле работает, как я ожидаю, что от точки зрения пользователя. Подумайте об этом: в моих тестах и в дикой природе функциональность будет работать с совершенно другими внутренними. И, несмотря на лучшие намерения сопровождающих, этот подход не обязательно не обязательно масштабируется до остальной части экосистемы JS, и может дать вам ложное чувство безопасности.
  4. Если я когда-нибудь решил изменить подход к функциональности и вместо этого использовать другую библиотеку, или напишите ее, все мои тесты внезапно станут устареть, и мне придется переписать их снова.

Теперь не поймите меня неправильно – это здорово, что они ушли на такие длины, чтобы создать «тестирование Backend», чтобы функциональные возможности могли быть проверены без DOM. Это, безусловно, полезно и имеет свое место. Но это не то, что я бы порекомендовал из-за проблем, которые я только что перечислил.

Что я после того, что следующее:

  1. Набор тестов, которые гарантируют на максимальную степень, что функциональность работает, как ожидалось (невозможно достичь 100% уверенности без сквозных испытаний, а не то, на данный момент я на данный момент). Это означает, что я хочу утверждать точное поведение функциональности с точки зрения пользователя в моих тестах.
  2. Я могу поменять или изменить реализацию функции (которая включает в себя любую библиотеку, используемую внизу) в любое время с минимальным воздействием на тесты.
  3. Я не должен быть знаком с реализацией функциональности для записи тестов.
  4. Мне нужно только использовать свои уже существующие и знакомые знания веб и веб-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, отсоедините их и т. Д… Все, что нужно! Инвестируя один или несколько часов с этим будет служить вам на всю оставшуюся вашу карьеру в качестве веб-разработчика. Довольно сладкое дело в моих глазах:)