Все кто занимается автоматическим тестированием, в частности написанием тестов, рано или поздно сталкиваются с одной и той же проблемой известной всем - ВРЕМЯ. Время, затраченное на прохождение всех тестов. Оно растет прямопропорционально с количеством написанных сценариев и никаким образом не хочет уменьшатся. Количество тестов растет - хорошо. Покрываем все больше и больше написаных фич. Время растет - плохо. Разработчики перестают прогонять тесты после изменения кода, ссылаясь на нехватку времени (и их можно понять). Оттого и получаем: и тесты есть и багов полно, которые могли быть выявлены этими самыми тестами. Данная участь коснулась и нашу команду.
Было принято решение запускать тесты в несколько потоков, причем удаленно, чтоб не мешали работать. Данную задачу решили с помощью уже имеющегося у нас 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 консоль перейдя по адресу
Запуск 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
То есть мы можем запустить наши тесты в пять потоков под Firefox, в пять потоков под Chrome и в один поток под IE.
Если вам не нужен такой набор браузеров их можно отрегулировать с помощью опциональных ключей -browser browserName=firefox, maxInstances=5
Так как наш сервер не имеет иксов, их надо запускать одновременно с запуском нод иначе мы не сможем подключится к нашим браузерам
Наша конечная команда для запуска нод выглядит следующим образом:
Итак что мы имеем?
Запущенный хаб и запущенная нода на одном инстансе. Но в нашем распоряжении имеется локальная сеть с множеством рабочих машин, а Selenium Grid как раз имеет возможность распространить выполнение тестов на другие машины.
Подключаемся по ssh к другой машине в сети. Устанавливаем Firefox и Chrome на ней, копируем наш selenium-server.jar а запускаем на машине его в режиме ноды. В нашем случае мы запустили помимо сервера еще на двух удаленных машинах ноды. Наша Grid Console стала выглядеть следующим образом:
На удаленных машинах мы специально ограничили ноды - 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 процесса на одну машину можно вешать безболезнено.
Огромная благодарность Дмитрию Лялюеву за соавторство.
Комментариев нет:
Отправить комментарий