Разделы портала

Онлайн-тренинги

.
Основы фреймворка автоматизации UI
21.06.2023 00:00

Автор: Марк Уинтерингэм (Mark Winteringham)
Оригинал статьи
Перевод: Ольга Алифанова

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

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

Неважно, используете ли вы “готовое” решение вроде Cypress, или же создаете свой собственный фреймворк - все они содержат схожие “корневые” компоненты. Глубокое понимание функционирования каждого компонента позволит получить от них максимум, и создать более прочные и надежные автоматизированные проверки.

Рассмотрим четыре основных “краеугольных камня”, из которых состоит фреймворк тест-автоматизации UI:

  • менеджер пакетов
  • средство запуска
  • драйвер UI
  • библиотека ассертов.

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

Управление множеством библиотек: менеджер пакетов

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

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

К примеру, в Maven, менеджере пакетов для Java, можно добавлять “зависимости” в файл POM.xml, чтобы определить, какие библиотеки нам нужны, а также версии каждой библиотеки:

<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
</dependencies>

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

Возможные менеджеры пакетов включают:


  • Maven (Java)
  • RubyGems (Ruby)
  • Pip (Python)
  • NPM (NodeJS)
  • NuGet (C#)

Запуск автоматизированных проверок: средство запуска

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

Средство запуска читает создаваемые нами файлы, чтобы “узнать”, какие проверки прогонять. К примеру:

  • Сначала мы создаем файл со словом Test в названии файла (ключевое слово Test помогает средству запуска идентифицировать файлы для прогона).
  • Внутри файла мы добавляем функцию или метод с каким-либо кодом, чтобы средство запуска точно знало, что это - автоматизированная проверка для прогона. К примеру, в Java можно добавить вот что, где @Test сообщает о методе exampleCheck():
@Test
public void exampleCheck(){
}
  • Затем мы добавляем какой-либо код внутрь метода, и там живет код нашей автоматизации (о котором мы узнаем в следующем разделе про UI-драйверы).

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

Средства запуска, которые мы можем использовать, включают:

  • Junit (Java)
  • Rspec (Ruby)
  • Unittest (Python)
  • Jest / Mocha (NodeJS)
  • Nunit (C#)

Взаимодействие с UI в режиме реального времени: UI-драйвер

Наши средства запуска позволяют создавать “оболочку” автоматизированной проверки - это значит, что выполняться будет все, что мы в эту “оболочку” поместили. Средству запуска неважно, автоматизирует ли ваш код браузер, вызывает ли API, или это просто кусок кода.

Если нам нужна возможность управлять интерфейсом браузера, нам нужен компонент, отвечающий за открытие браузера и позволяющий нам взаимодействовать с его элементами. За это отвечает UI-драйвер.

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

 

Инструментом вроде Selenium-WebDriver можно воспользоваться для объявления элемента, который мы хотим найти (при помощи findElement()), и для сообщения, что мы хотим сделать с этим элементом - при помощи click(). Когда этот код срабатывает, он отправляется в копию драйвера, который переводит код в инструкцию для конкретного браузера. Цикл затем закрывается браузером, сообщающим драйверу, что действие выполнено.

Код ниже демонстрирует, как выглядит findElement() для элемента, соответствующего CSS-селектору createRoom, а также спрашивает, отображается ли этот элемент на экране:

Boolean buttonExists = driver.findElement(By.cssSelector("#createRoom")).isDisplayed();

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

UI-драйверы, которыми можно воспользоваться, включают:

  • Selenium-WebDriver (для нескольких языков)
  • Watir (Ruby)
  • Native JavaScript (NodeJS)

Сработал ли код так, как надо? Библиотека ассертов

Мы обсудили менеджеры пакетов, средства запуска и UI-драйверы. При помощи этих компонентов у нас есть все средства, чтобы создать взаимодействующий с UI фреймворк.

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

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

assertEquals(buttonExists, true);

Этот код проверяет, равно ли значение переменной buttonExists, извлеченное при помощи UI-драйвера, истине. Если оно равно истине, проверка пройдет. Если это не так, она упадет.

У многих средств запуска есть свои собственные, встроенные  библиотеки ассертов. Однако существуют и отдельные доступные для использования библиотеки:

  • Hamcrest (Java)
  • Chai (NodeJS)

Объединяем все: пример кода

Это был быстрый обзор ряда ключевых компонентов фреймворка тест-автоматизации UI. Если вы хотите узнать больше о том, как совместить эти компоненты и получить фреймворк, посмотрите на мое введение в UI-фреймворк на GitHub: https://github.com/mwinteringham/intro-to-ui/

Дополнительная литература

Panel Discussion: Strategy and Approach to UI Automation (Gwen Diagram, Corina Pip, Dana Aonofriesei, Niranjani Manoharan)

Starting Out With UI Automation Using SpecFlow, Louise Gibbs

Getting Started With Cross Browser Testing | MoT

The Building Blocks of the Internet, Mark Winteringham

Обсудить в форуме