Выпуск 15. Май 2014

Модульное тестирование под AnyEvent | Содержание | Обзор CPAN за апрель 2014 г.

Тестирование интерфейса веб-приложений. Применение WWW::WebKit

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

Selenium WebDriver

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

Selenium WebDriver имеет удобный API, который позволяет получить доступ к его функциям из приложений, написанных на различных языках программирования. Как правило, используется либо Selenium Server, либо непосредственно WebDriver какого-либо браузера, к которому по сети может подключаться ваше приложение и отправлять команды в JSON-формате по HTTP-протоколу, и получать данные о реакции браузера. Спецификация этого протокола была принята консорциумом W3C как интернет-стандарт WebDriver. На текущий момент действует уже 12-я версия черновика.

Основные преимущества Selenium WebDriver

  • Это интернет-стандарт, с ним знакомы многие QA-команды, тестирующие веб-приложения вне зависимости от используемого языка программирования.

  • Можно тестировать веб-приложение на множестве различных актуальных браузеров: Firefox, Chrome и IE.

Недостатки Selenium WebDriver

  • Необходимость установленного веб-браузера для выполнения тестов (IE также потребует Windows-инсталляции).

  • Временные затраты на запуск браузера для теста.

  • Необходимость иметь запущенный графический сервер (или хотя бы виртуальный, например, Xvfb).

  • Запущенный экземпляр службы Selenium Server/WebDriver.

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

Perl-модули для взаимодействия с Selenium

Существует несколько Perl-модулей для взаимодействия с Selenium:

  • WWW::Selenium — самый старый и известный модуль для работы ещё со старой версией Selenium RC-сервера, протокол которого пока поддерживается в Selenium Server. Дистрибутив имеет в своём составе модуль Test::WWW::Selenium, который удобен для непосредственного создания тестов веб-приложения.

  • Selenium::Remote::Driver — актуальный модуль для работы с современным API Selenium WebDriver. Также включает в свой состав модуль для тестирования Test::Selenium::Remote::Driver.

Альтернативы Selenium

Phantomjs — это проект на основе движка рендеринга веб-страниц WebKit (QT-порт WebKit), который не требует графического сервера для работы. Phantomjs управляется с помощью скриптов на JavaScript/CoffeeScript, позволяя загружать страницы, делать скриншоты, конвертировать и сохранять страницы в pdf-формате. Скрипт может выполнять код в контексте открытой страницы браузера, позволяя взаимодействовать с DOM-элементами страницы.

Начиная с версии 1.8 Phantomjs включает компонент GhostDriver, который реализует WebDriver API. Таким образом, появляется возможность работать с Phantomjs непосредственно с помощью существующих средств работы с Selenium WebDriver.

Perl-модуль Wight — это модуль для тестирования веб-приложений, который был создан специально для работы с Phantomjs, используя существующий там интерфейс WebDriver поверх WebSocket.

Можно также упомянуть модуль WWW::Mechanize::Firefox, который использует браузер Firefox с установленным расширением MozRepl, которое позволяет управлять браузером с помощью команд telnet-сессии.

WWW::WebKit — это Perl-модуль, построенный на основе Gtk3::WebKit — обвязке к порту WebKitGTK+, используемого в проекте Gnome. На устройстве и интерфейсе этого модуля и хотелось бы остановиться в рамках данной статьи.

WWW::WebKit

Модуль WWW::WebKit был создан Стефаном Сейфертом (Stefan Seifert). Вероятно некоторые знают его как одного из авторов CiderWebmail и CiderCMS, он также выступал в лайтингах третьего дня на YAPC::Europe в Киеве в 2013 г. с докладом о них. Модуль был задуман как альтернатива реализации WWW::Selenium, которая вместо использования сервера Selenium использовала бы встроенный движок рендеринга веб-страниц Gtk3::WebKit. По этой причине модуль почти один в один копирует API WWW::Selenium, что позволяет обеспечить простой перевод существующих тестов от одного модуля к другому.

Применение встроенного движка рендеринга веб-страниц даёт несколько преимуществ:

  • Меньший объём используемой памяти.
  • Нет необходимости в дополнительных программных средствах и заботе об их управлении.
  • Упрощается параллельный запуск тестов.

Недостатки:

  • Требуется виртуальный графический сервер Xvfb.
  • Отображение веб-страниц проверяется только на одном из существующих движков — WebKit.

API WWW::WebKit

my $webkit = WWW::WebKit->new(xvfb => 1);
$webkit->init;

В данном примере создаётся объект WWW::WebKit. Параметр xvfb указывает, есть ли необходимость запуска виртуального фреймбуфера Xvfb, что актуально если вы пытаетесь запустить скрипт на сервере без графического интерфейса.

Перед выполнением каких-либо операций над объектом $webkit необходимо выполнить его инициализацию с помощью вызова init(). В этом случае будет запущен Xvfb (если требуется) и инициализированы WebKit и Gtk3.

$webkit->open("https://www.google.com");

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


eval {
    local $SIG{ALRM} = sub { die };
    alarm 5;
    $webkit->open("http://not_correct_url");
    alarm 0;
};

warn "failed to load URL" if $@;

Локатор

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

тип локатора = значение

Обрабатываются следующие типы локаторов:

  • label=текст — поиск текстового элемента с соответствующим содержимым;
  • link=тест — поиск ссылки с соответствующим текстом;
  • value=значение — поиск элемента с указанным значением атрибута value;
  • index=значение — поиск элемента option с заданным номером позиции;
  • id=идентификатор — поиск элемента по идентификатору id;
  • css=селектор CSS — поиск по CSS-селектору;
  • class=класс — поиск по имени класса;
  • name=имя — поиск по атрибуту name элемента;
  • xpath=выражение xpath — поиск по заданному XPath-выражению.

Если тип селектора не указан, то по умолчанию считается, что задано выражение XPath.

Примеры использования локатора:

# Получить значение элемента с атрибутом name = "q"
$webkit->get_value('name=q');

Получение данных со страницы

Список методов, реализованных в WWW::WebKit для получения текстовой информации:

  • get_text($locator) — получить значение текстового элемента;
  • get_body_text() — текстовое содержимое <body>;
  • get_title() — заголовок страницы;
  • get_value($locator) — значение элемента;
  • get_attribute($locator) — значение атрибута;
  • get_html_source() — полный исходный код страницы.

События мыши

WWW::WebKit позволяет генерировать события мыши:

# Клик на кнопке с именем btnG
$webkit->click("name=btnG");
# Ожидание загрузки страницы (или пока не пройдёт 5 секунд)
$webkit->wait_for_page_to_load(5000);

В данном примере происходит клик мыши по элементу, после чего происходит ожидание загрузки страницы с таймаутом 5 секунд. Стоит отметить, что если перезагрузка документа не происходит, например, выполнен AJAX-запрос, то необходимо использовать функцию wait_for_pending_requests:

# Клик на кнопке с id="someid"
$webkit->click("id=someid");
# Ожидание выполнения ajax-запроса (или пока не пройдёт 5 секунд)
$webkit->wait_for_pending_request(5000);

Кроме клика существуют также следующие методы:

  • mouse_over($locator) — мышь движется поверх элемента;
  • mouse_down($locator) — нажата левая кнопка мыши;
  • mouse_up($locator) — отпущена левая кнопка мыши;
  • native_drag_and_drop_to_position(...) — перемещение элемента к заданной позиции;
  • native_drag_and_drop_to_object(...) — перемещение одного элемента на другой.

События клавиатуры

Для генерации нажатий клавиш используются средства модуля X11::Xlib, поскольку имеющихся возможностей самого Gtk3 оказалось недостаточно.

# установка значения поля элемента с именем "q"
$webkit->type("name=q", "hello world");

# тоже самое, но с генерацией нажатий кнопок
# клавиатуры для каждого символа строки
$webkit->type_keys("name=q", "hello world");

Выполнить нажатие отдельной клавиши можно с помощью метода key_press().

Операции с формами

Для работы с формами реализовано несколько методов.

  • submit($locator) — отправка формы по заданному локатору:

    $webkit->submit("id=gbdf");
    $webkit->wait_for_page_to_load(2500);
  • select($select_locator, $option_locator) — выбор опции в элементе <select>;
  • check($locator) — установка “галочки” элемента checkbox;
  • uncheck($locator) — снятие “галочки” с элемента checkbox.

API Test::WWW::WebKit

Был создан модуль Test::WWW::WebKit, предназначенный для построения тестов с использованием WWW::WebKit. Назначение тестовых функции интуитивно понятно, название многих методов построено из названия метода родительского класса и суффикса _ok или _is. Пример теста с отправкой формы и ожидания ответа:

use Test::WWW::WebKit;
my $webkit = Test::WWW::WebKit->new(xvfb => 1);
$webkit->init;

# Загрузить страницу
$webkit->open_ok("http://www.google.com");

# Ввести текст в поле формы
$webkit->type_ok("name=q", "hello world");

# Успешная отправка формы
$webkit->submit_ok("id=gbqf");

# Ожидание ответа
$webkit->wait_for_pending_requests(5000);

# Заголовок совпал с ожидаемым
$webkit->title_is("foo");

Заключение

Надеюсь, данный обзорный материал дал вам представление о том, какие средства применяются для тестирования UI веб-приложений. Каждое средство имеет свои преимущества и недостатки, а также сферу применения. На мой взгляд, WWW::WebKit, несмотря на определённую недоработанность и незрелость, заслуживает внимания как удобная легковесная среда тестирования. WebKitGtk+ имеет широкий спектр возможностей, включая и создание скриншотов, и возможностей конвертации веб-страниц в pdf. WWW::WebKit вполне может быть доработан для включения этих возможностей, в соответствии с декларируемой совместимостью с API WWW::Selenium.

Владимир Леттиев


Модульное тестирование под AnyEvent | Содержание | Обзор CPAN за апрель 2014 г.
Нас уже 1393. Больше подписчиков — лучше выпуски!

Комментарии к статье