Локаторы веб-элементов в тест-автоматизации |
12.08.2019 00:00 | ||||
Автор: Энди Найт (Andy Knight) Если вы занимаетесь тест-автоматизацией через веб-интерфейс (например, при помощи Selenium WebDriver), то, возможно, тратите много рабочего времени на поиск элементов на странице – к примеру, кнопок, полей ввода и блоков. Поиск нужных элементов может быть сложным делом, особенно в тех случаях, когда у них нет уникальных идентификаторов или имен классов. Это руководство поможет вам профессионально находить любые веб-элементы. Что такое веб-элементы? Веб-элемент – это индивидуальная сущность, генерирующаяся на веб-странице. Элементы – это все то, что пользователь видит (а иногда и не видит) на странице – заголовки, кнопки "ОК", поля ввода, текстовые блоки… Элементы в HTML определяются через имя тэга, атрибуты и содержание. У них также могут быть дочерние элементы – например, таблицы. CSS может применяться к элементам и менять их цвета, размеры и расположение. Языки программирования обычно получают доступ к веб-элементам как к нодам в объектной модели документа (DOM). Что такое локаторы веб-элементов? Веб-элементы и локаторы – это разные вещи. Локатор веб-элемента – это объект, который находит и возвращает веб-элементы на странице по заданному запросу. Короче говоря, локаторы находят элементы. Зачем нужны локаторы? Как пользователи, мы взаимодействуем с веб-страницами визуально. Мы смотрим, скроллим, кликаем и печатаем посредством браузера. Тест-автоматизация, однако, взаимодействует со страницами программно: ей нужен закодированный способ поиска и манипулирования теми же самыми элементами. Традиционная автоматизация не будет "смотреть" на страницу, как человек – вместо этого она будет искать через DOM. (Более современные технологии автоматизации позволяют визуальное тестирование – об этом будет сказано чуть позже). Selenium WebDriver разделяет вопросы поиска элементов и взаимодействия с ними. Вызовы WebDriver для этих двух целей часто идут подряд.
WebDriver предоставляет следующие типы запросов для локаторов через "By": provides the following locator query types using “By”:
Какой из них лучше? Обсудим далее. Локаторы могут возвращать несколько элементов, или вообще их не вернуть! Вот пример:
Большие тест-фреймворки часто используют шаблоны дизайна для структурирования локаторов и взаимодействий. Модель Page Object организует локаторы и методы действий в классы – по странице или по компоненту. Однако я крайне рекомендую шаблон Screenplay, а не Page Object, потому что части Screenplay лучше подаются повторному использованию и масштабированию. Вне зависимости от модели локаторы необходимы. Как найти элементы? Элементы могут с трудом поддаваться поиску, когда вы пишете локаторы для тест-автоматизации. Для упрощения работы я использую инструменты разработчика Chrome вместе с моей IDE. Почему Chrome?
Чтобы исследовать любую страницу в Chrome, просто кликните правой кнопкой на любом месте страницы: Вуаля! Инструменты разработчика откроются. Для поиска веб-элементов мы воспользуемся вкладкой Elements. В Chrome легко выделить элемент визуально. Выберите инструмент "Select" в верхнем левом углу панели инструментов разработчика (она выглядит как квадрат с курсором). Иконка должна поменять цвет на синий. Затем переместите курсор к нужному элементу на странице. Вы увидите, как каждый элемент подсвечивается, когда вы наводите на него мышь. Соответствующий исходный HTML-код на вкладке Elements также будет подсвечен. Чудненько! Кликните на нужном элементе, чтобы подсветка сохранилась после смещения курсора. Теперь вы можете изучить тег элемента, классы, атрибуты, содержание, родительские и дочерние элементы. Как писать хорошие локаторы? Поиск элемента – это полдела. Создание уникального запроса для локатора – вот вторая половина. Если локатор чересчур широк, он будет возвращать ложноположительные значения. При слишком узком подходе он начнет ломаться при любом изменении DOM, и его будет сложно читать другим людям. Лучший подход здесь такой – пишите наиболее простой запрос, который уникально идентифицирует целевой элемент или элементы. Мой список предпочтения типов запросов в порядке убывания:
Уникальные ID, имена и имена классов крайне упрощают создание локаторов: запросы будут краткими и не требуют дополнительных якорей. Всегда ратуйте, чтобы ваши разработчики использовали уникальные идентификаторы (например, имена классов) для всех элементов. Однако у многих элементов таких идентификаторов нет, и локаторам приходится полагаться на более сложные CSS-селекторы и (содрогнувшись) XPath. Если это случилось с вами, вот мои рекомендации:
Всегда тестируйте локаторы, в них часто встречаются ошибки синтаксиса и ложноположительные значения. Chrome DevTools упрощает их тестирование – нажмите Ctrl+F на вкладке элементов и вставьте запрос локатора в поле поиска. DevTools подсветит все соответствующие элементы по порядку. Шик-блеск-красота! Если я не могу разобраться, почему локатор в тесте не срабатывает, я делаю следующее:
Что делать, если тесты нестабильны? Тестирование через Web UI часто критикуют за нестабильность, потому что тесты часто падают из-за непредвиденных причин. Однако большая часть ненадежности, с которой сталкиваются тестировщики Web UI (и, зачастую, пользователи Selenium WebDriver как такового) связана с тем, что все Web-взаимодействия изначально создают гоночные условия. Автоматизация и браузер работают независимо друг от друга, и взаимодействие должно синхронизироваться с состоянием страницы. В противном случае WebDriver будет выдавать исключения из-за таймаутов, устаревших и не найденных элементов. В ряде случаев эти проблемы возникают не каждый раз, поэтому их тяжело отследить и исправить. Лучший способ избежать гоночных условий таков – всегда ожидайте существования элемента, прежде чем взаимодействовать с ним. Это кажется элементарным, но про это легко забыть. Пакеты Selenium WebDriver всегда предлагают какую-то разновидность объекта WebDriverWait, заставляющего драйвер ожидать истинности определенного условия перед дальнейшими действиями. Простейший способ проверить, существует ли элемент – это проверить список элементов, возвращаемый вызовом FindElements (для списка элементов) и убедиться, что он непустой. Добавление дополнительного вызова для каждого взаимодействия может показаться затратным, однако дизайн-шаблоны хорошо спроектированных фреймворков (например, Screenplay) могут автоматически осуществлять подобные проверки. Еще одна хорошая практика – всегда получать "свежие" элементы. Иногда автоматизация вначале получит ряд элементов, а затем через второй запрос получит следующую часть. Или же, в случае с Page Object Factory (никогда ей не пользуйтесь – если в трех словах, она отвратительна), элементы получаются один раз при конструировании Page Object, а затем на них ссылаются. Вне зависимости от способа – чем дольше существует объект на веб-странице, тем более он подвержен тому, чтобы устареть и вызвать исключения. Я видел элементы, необъяснимо устаревающие, даже если они еще присутствовали на странице. Всегда запрашивайте элемент тогда, когда он нужен – в этом случае он не успеет устареть! Как искусственный интеллект может помочь в тестировании Web UI? Ряд новых основанных на ИИ проектов и продуктов направлен на улучшение автоматизированного тестирования Web UI по сравнению с традиционными методами:
Множество инструментов тестирования, основанных на ИИ, очень полезны, но держите в уме, что под капотом они все-таки пользуются локаторами. |