...какие события лучше, нативные или синтезированные?

В предыдущей статье я объяснил, чем отличается эмуляция действий пользователя в FirefoxDriver при помощи нативных и синтезированных событий. И теперь пришло время ответить на вопрос – какой способ лучше?

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

Один из основных аргументов, подкрепляющих эту точку зрения, звучит так: “а вдруг синтезированные события синтезированы неправильно – каких-то не хватает, какие-то лишние, нарушен порядок”.

Не исключено, что так оно и есть :)

Однако, во-первых, при генерации синтезированных событий Selenium использует специальный интерфейс nsIDOMWindowUtils, который предназначен как раз для эмуляции действий пользователя. Разработчики браузера Firefox позаботились о том, чтобы синтезированные события выглядели достаточно натуралистично.

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

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

Зато нативные события обладают целым рядом недостатков, которые не присущи синтезированным событиям.

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

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

Во-вторых, нативные события перемещения мыши вызывают у браузера впечатление, что мышь и правда двигается.

Это приводит к возникновению различных “побочных эффектов”. Например, собираемся мы кликнуть по какому-нибудь элементу. Сначала Selenium наводит на него мышь, чтобы всё выглядело естественно. Двигаясь к элементу, мышь пробегает над каким-нибудь выпадающим меню. Оно, естественно, выпадает – и накрывает элемент. Однако Selenium не обращает на это внимания и кликает в том месте, где находится требуемый элемент. Но нажатие выполняется по элементу выпавшего меню, потому что именно он находится в данный момент в той точке, куда кликнула мышь. Чтобы справиться с этой проблемой, приходится строить разные костыли. Например, сначала подвигать мышь вниз, чтобы потом она наводилась на нужный элемент не сверху (где находится меню), а снизу. Сами понимаете, изящности тестам это не добавляет. А синтезированные события таких побочных эффектов не вызывают.

Вот ещё один пример такого же рода. Есть два блока div – побольше и поменьше, маленький находится внутри большого. С обоими блоками связаны обработчики нажатия, причём разные. Теперь попробуйте ответить на вопрос, что будет, если кликнуть по большому блоку? Selenium эмулирует нажатие кнопки мыши в центральной точке, и если эта точка перекрывается маленьким вложенным блоком – нативные события вызовут срабатывание обработчика маленького блока. А если центральная точка не перекрывается маленьким блоком – тогда будет вызван обработчик большого блока. И если расположение этих блоков меняется динамически, маленький блок либо оказывается внутри, либо нет (например, в зависимости от размера окна браузера) – результат попытки кликнуть по большому блоку становится труднопредсказуемым. И опять приходится делать костыли, например, кликать не в центр, а в точку, отстоящую на два пикселя от левого края блока. Оно вам надо?

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

Ну и напоследок ещё один аргумент, в пользу синтезированных событий – производительность.

Сравните среднее время выполнения тестов на сервере непрерывной интеграции Selenium, где запускается один и тот же набор тестов с нативными и синтезированными событиями.

Реализация, использующая синтезированные события, работает в среднем примерно на 20% быстрее.

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


Алексей Баранцев

Автор:

Если вам понравилась эта статья, вы можете поделиться ею в социальных сетях (кнопочки ниже), а потом вернуться на главную страницу блога и почитать другие мои статьи.
Ну а если вы не согласны с чем-то или хотите что-нибудь дополнить – оставьте комментарий ниже, может быть это послужит поводом для написания новой интересной статьи.

Мои тренинги
А ещё есть? Конечно!