Выпуск 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 г. →