21 октября 2013 г.

Переход на Selenium 2 + PhantomJS

В этом посте я запишу, как я переходил с Selenium RC на Selenium 2. Переход был мотивирован использованием PhantomJS в качестве браузера. В PhantomJS встроен Ghost Driver, который является WebDriver в том смысле, который использует Selenium 2. Но мои предыдущие тесты PHPUnit использовали класс PHPUnit_Extensions_SeleniumTestCase, который не умеет работать с WebDriver. Нужно было его заменить на PHPUnit_Extensions_Selenium2TestCase вместе со всем синтаксисом тестов.



Имеющееся окружение

Тесты, записанные с помощью Selenium IDE, которые, благодаря Jenkins, при каждом hg push конвертируются в PHPUnit TestCase с помощью selenium2php. После этого запускается сам PHPUnit на полученных php-файлах тестов. При конвертации автоматически проставляется IP-адрес виртуальной машины, где находится сервер Selenium RC, который выполняет тесты в браузере Firefox.

Цель

Получить тоже самое, только вместо Firefox консольный PhantomJS и предполагаемое увеличение производительности как следствие.

Особенности Selenium 2

Selenium 2 имеет свои особенности, которые следует учитывать.
1. Все переходы по ссылкам теперь не нуждаются в ожидании, то есть нет необходимости в clickAndWait, достаточно просто click, если дело касается обычной ссылки (не js функции перехода). Причина этого в том, что теперь все вызовы блокирующие, то есть не асинхронные, как отмечают на stackoverflow, это хорошо.
2. При работе с javascript никаких блокировок не происходит, и нужно вручную вставлять команды ожидания. Например, waitForElementPresent на локатор, который появляется после выполнения AJAX-запроса.
3. Вы не можете манипулировать невидимыми элементами.
Но особенности появились и у PHPUnit Selenium2TestCase. Главное, это почти полностью новый синтаксис. Все команды принимают только один аргумент, а некоторые старые теперь называются по-другому. Например, вместо open(), теперь url().
Появилась необходимость найти способы обхода этих новшеств.

Способ 1: Адаптер.

Я решил попробовать написать адаптер MigrationToSelenium2 для перехода от PHPUnit_Extensions_SeleniumTestCase к PHPUnit_Extensions_Selenium2TestCase. То есть планировал продолжить использовать selenium2php для конвертации тестов в формате Selenium RC, но наследуя свой Migration класс, который осуществит использование методов по формату PHPUnit Selenium2.
Когда дошло дело до AJAX-запросов и манипуляцией видимости элементов на странице, я понял, что тесты оставить неизменными не получится. А раз тесты всё равно менять, то заодно решил поменять и конвертер. В данный момент нет планов поддерживать Migration Class.

Способ 2: selenium2php - автоматический конвертер Selenium IDE тестов в Selenium 2

Я расширил проект selenium2php для поддержки формата Selenium2. В описании проекта на Github'е есть примеры использования. Вкратце, теперь из html тестов формата Selense с помощью консольной утилиты получаем файл теста с синтаксисом для класса PHPUnit_Extensions_Selenium2TestCase.

Запуск тестов на PhantomJS

Скачиваем (если еще нет) Selenium Server (он же RC) и PhantomJS. Запускаем Selenium grid hub и подключаем к нему PhantomJS как клиента:
java -jar selenium.jar -role hub
phantomjs --webdriver=1408 --webdriver-selenium-grid-hub=http://127.0.0.1:4444

Окружение для выполнение тестов готово. Теперь нужно убедиться, что в тесте целевым браузером указана строка "phantomjs", а адрес и порт совпадают с grid hub.
Остаётся запустить PHPUnit:
php phpunit.phar YourTest.php

Вывод

Исправление готовых тестов, хоть и в Selenium IDE, для поддержки Selenium 2 заняло много времени, но это всё равно быстрее и удобнее, чем создавать и позже исправлять тесты на языке php. Конвертер selenium2php облегчает эту работу.

К сожалению, в результате обнаружились серьёзные недостатки.
1. Проверялось всё на PHPUnit 3.7.27, Selenium Server 2.37, PhantomJS 1.9.2, но в итоге на виртуальной машине WinXP связка была нестабильная и в 70% случаях при запуске нового теста выдавалось FORWARDING_TO_NODE_FAILED. На Win7 это случалось гораздо реже, примерно 1 тест из 50. Но сам факт наличия таких выпадов очень мешает при использовании CI.
2. Еще одно разочарование - скорость выполнения скрипта. Хоть PhantomJS и консольный, но на выполнение всех тестов у него уходит 14 минут, вместо 19 минут с Selenium 1 + Firefox.
Вместе эти два недостатка заставили меня временно отложить Selenium 2 до лучших времён.

1 комментарий:

  1. Спасибо, можете почитать также мою статью про Selenium: http://plutov.by/post/test_phpunit_selenium

    ОтветитьУдалить