1/19/2015

Selenium Grid with Jenkins - хороший тандем для параллели тестов



Все кто занимается автоматическим тестированием, в частности написанием тестов, рано или поздно сталкиваются с одной и той же проблемой известной всем - ВРЕМЯ. Время, затраченное на прохождение всех тестов. Оно растет прямопропорционально с количеством написанных сценариев и никаким образом не хочет уменьшатся. Количество тестов растет - хорошо. Покрываем все больше и больше написаных фич. Время растет - плохо. Разработчики перестают прогонять тесты после изменения кода, ссылаясь на нехватку времени (и их можно понять). Оттого и получаем: и тесты есть и багов полно, которые могли быть выявлены этими самыми тестами. Данная участь коснулась и нашу команду.

Было принято решение запускать тесты в несколько потоков, причем удаленно, чтоб не мешали работать. Данную задачу решили с помощью уже имеющегося у нас Jenkins’a и Selenium Grid.
Итак приступим.
Дано:
  • проект Ruby on Rails
  • тесты Cucumber with Capybara
  • настроенный Jenkins на прохождение браузерных тестов в одном потоке
  • Много рабочих компов в одной локальной сети.


Немного о Selenium Grid.
Selenium Grid - мощный инструмент позволяющий распространить выполнение ваших тестов на несколько машин. Предоставляет возможность управлять несколькими средами из центральной точки, что позволяет легко запускать тесты с большим сочетанием браузеров и ОС.
Исполняющий файл Selenium Grid - selenium_server_standalone.jar который содержит в себе все необходимые нам дистрибутивы, а именно selenium hub (центр управления и мониторинга) и selenium node (удаленные браузеры).


Запуск selenium hub
Для запуска скачиваем файл selenium-server.jar на наш сервер и запускаем hub с помощью следующей команды:



Команда выполняется с директории в которой находится данный jar файл, либо в команде запуска добавляется путь к данному файлу. По умолчанию hub запускается на 4444 порту. Если имеется необходимость, то можно указать порт вручную добавив в команду запуска ключ -port



Также сервер поддерживает другие способы запуска, с которыми можно ознакомится в мануале.
После успешного запуска hub’a имеется возможность просмотреть на его GUI консоль перейдя по адресу


grid_console.png


Запуск selenium node
Далее нам необходимо запустить ноды. Иными словами это браузеры, где будут выполняться наши тесты.
Запуск нод выполняется следующей командой:



по умолчанию ноды запускаются на 5555 порту. Его также можно изменить указав опциональный параметр -port. Обратите внимание, что в команде запуска ноды присутствует ключ на наш запущенный hub. Таким образом, если мы меняли порт при запуске hub’a его надо изменить и в запуске ноды.
java -jar selenium-server.jar -role node -hub http://localhost:4445/grid/register -port 5556
В команде запуска также присутствует ключ -role. Если его поставить в значение node то ноды будут запущены для WebDriver’a (Selenium2) и Remote Control (Selenium). Если вы не используете Remote Control то имеет смысл изменить значение параметра на webdriver



Перейдя в Grid Console по адресу http://127.0.0.1:4445/grid/console вы должны увидеть следующее
selenium_node.jpg
То есть мы можем запустить наши тесты в пять потоков под Firefox, в пять потоков под Chrome и в один поток под IE.
Если вам не нужен такой набор браузеров их можно отрегулировать с помощью опциональных ключей -browser browserName=firefox, maxInstances=5
Так как наш сервер не имеет иксов, их надо запускать одновременно с запуском нод иначе мы не сможем подключится к нашим браузерам
Наша конечная команда для запуска нод выглядит следующим образом:


Итак что мы имеем?
Запущенный хаб и запущенная нода на одном инстансе. Но в нашем распоряжении имеется локальная сеть с множеством рабочих машин, а Selenium Grid как раз имеет возможность распространить выполнение тестов на другие машины.
Подключаемся по ssh к другой машине в сети. Устанавливаем Firefox и Chrome на ней, копируем наш selenium-server.jar а запускаем на машине его в режиме ноды. В нашем случае мы запустили помимо сервера еще на двух удаленных машинах ноды. Наша Grid Console стала выглядеть следующим образом:
several_nodes.png


На удаленных машинах мы специально ограничили ноды - Chrome 2 шт и Firefox 2 шт исключив ненужный нам IE.
То есть теперь мы можем запустить наши тесты в 9 потоков под Firefox и 9 потоков под Chrome.


Создание upstart сервисов для запуска selenium grid


Для запуска selenium hub и selenium node можно воспользоваться upsatrt’ом. Во первых это правильно, во вторых достаточно удобно.
Для создания сервиса selenium hub выполняем следующиее:
nano /etc/init/selenium-hub.conf
В файлик записываем следующие настройки




Теперь selenium hub можно запустить с помощью команды


service selenium-hub start


Остановить:

service selenium-hub stop


Перезапустить:


service selenium-hub restart


Такой же конфигурационный файл надо создать и для selenium node



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


При запуске тестов теперь необходимо использовать команду с новой переменной, а точнее с двумя SELENIUM, BROWSER. Ключ SELENIUM является обязательным. С помощью него мы говорим, что будем использовать другое окружение, в то время как параметр BROWSER является необязательным. По умолчанию наши тесты будут выполнятся под управлением Firefox, если мы захотим запустить их под управлением Chrome следует указать переменную окружения BROWSER=chrome.
Итак идем в Jenkins и меняем нашу команду запуска тестов на

SELENIUM=remote bundle exec cucumber

для запуска под Firefox и

SELENIUM=remote BROWSER=chrome bundle exec cucumber

для запуска под Chrome


На данном этапе наши тесты будут запускаться на удаленном браузере, но только в один поток.


Установка gem parallel_tests
Для того, чтобы наш сервер выполнял тесты в несколько потоков нам необходимо их распаралелить. Для этих целей мы использовали гем parallel_tests
Установка стандартная. Добавляем gem "parallel_tests", :group => :development в Gemfile
Далее идем в настройки сборки на Jenkins’e
Нам необходимо создать дополнительные базы данных для выполнения тестов.
А именно:



и изменяем команду запуска согласно инструкции гема

SELENIUM=remote BROWSER=chrome bundle exec rake parallel:features[8]


Также имеет смысл отключить запуск Xvfb перед запуском сборки, так как мы его запускаем вместе с нодами.

Теперь наша сборка будет выполняться в 8 потоков под управлением Chrome.
При прохождении тестов можно открыть Grid Console и наблюдать за процессом распараллеливания.


P.S. В нашем случае нам удалось сократить время прохождения тестов с 50 минут в один поток на локальной машине до 8.8 минут в 10 потоков на удаленных браузерах. И 10 потоков - это не предел, когда обладаешь большой сетью )))

На удаленных машинах при поднятии нод наблюдали за загрузкой процессора при выполнении тестов - она не могла нас не порадовать. 2 процесса на одну машину можно вешать безболезнено.

Огромная благодарность Дмитрию Лялюеву за соавторство.

Комментариев нет:

Отправить комментарий