Запуск тестов в selenium на сервере без монитора

Selenium

Перед каждым разработчиком рано или поздно встает вопрос тестирования его кода. При чем unit-тестирование покрывает не всегда и не все нужды. Для более полного обеспечения качества создаваемого проекта приходится прибегать и к приемочному тестированию.

На сегодняшний день дела обстоят более менее не плохо. Есть набивший многим оскомину селениум. Есть Mink Константина Кудряшова, который позволяет писать функциональные/приемочные тесты в достаточно дружелюбном стиле. И при чем в качестве драйвера использовать не только селениум, среди перечня доступных есть вполне достойный безголовый zombie. Но, после моих тестов наиболее точным тестирование оказалось только через селениум. Зомби по каким-то причинам выкидывал ошибки при парсинге jquery.

Но, минус селениума в том, что ему для работы нужен браузер (по традиции firefox). А firefox требует для запуска дисплей. А на моем сервере, который используется для Continuous Integration монитора нет (это же сервер). Решение было найдено в лице утилиты Xvfb, представляющей из себя виртуальный дисплей.

sudo apt-get install xvfb

На просторах сети даже описываются способы создания скриншотов сайтов с её помощью.

Запуск дисплея

Запуск программ, которые будут отображать свой гуй на виртуальном мониторе осуществляется командой:

xvfb-run [OPTION ...] COMMAND
Run COMMAND (usually an X client) in a virtual X server environment.
Options:
-a        --auto-servernum          try to get a free server number, starting at
                                    --server-num
-e FILE   --error-file=FILE         file used to store xauth errors and Xvfb
                                    output (default: /dev/null)
-f FILE   --auth-file=FILE          file used to store auth cookie
                                    (default: ./.Xauthority)
-h        --help                    display this usage message and exit
-n NUM    --server-num=NUM          server number to use (default: 99)
-l        --listen-tcp              enable TCP port listening in the X server
-p PROTO  --xauth-protocol=PROTO    X authority protocol name to use
                                    (default: xauth command's default)
-s ARGS   --server-args=ARGS        arguments (other than server number and
                                    "-nolisten tcp") to pass to the Xvfb server
                                    (default: "-screen 0 640x480x8")

В нашем случае требуется запустить в окружении этой утилиты именно селениум:

DISPLAY=:99 xvfb-run -a -n 1 -l -s "-screen 0, 1024x768x8" java -jar /usr/local/bin/selenium-server

Но, это еще не все. Мало запустить selenium, нужно ещё и тесты. Тогда команда запуска тестов будет представлять примерно следующий вид:

DISPLAY=:99 xvfb-run -a -n 1 -l -s "-screen 0, 1024x768x8" java -jar /usr/local/bin/selenium-server.jar & php bin/phpunit -c test/phpunit.xml

Здесь сначала активируем виртуальный дисплей

DISPLAY=:99 xvfb-run -a -n 1 -l -s "-screen 0, 1024x768x8"

потом запускаем selenium, который будет выводить на этом дисплее окно firefox

java -jar /usr/local/bin/selenium-server.jar

и наконец запускаем сами тесты

& php bin/phpunit -c test/phpunit.xml

Запуск PHP

Но, тут есть один нюанс. А именно, selenium должен обращаться к какому-то веб-серверу. Если CI работает не под root (что скорее всего), то он вряд ли сможет перед началом тестирования сборки запускать nginx или apache с виртуальным хостом в нужной директории. Тогда вспоминаем, что в php 5.4 нам подарили built-in server, для запуска которого достаточно выполнить команду

php -S localhost:8888

чтобы запустить сервер на соответствующем хосте и порту.

Чтобы реализовать у себя запуск сервера перед тестами и его остановку после, воспользуемся примером из статьи Using PHP’s built-in web server in your test suites. Для этого внесем в начало bootstrap-файла несколько строк кода:

    $host = 'localhost';
    $port = '8888';
    // Command that starts the built-in web server
    $command = sprintf('php -S %s:%d -t %s >/dev/null 2>&1 & echo $!', $host, $port, '.');
    // Execute the command and store the process ID
    $output = array();
    exec($command, $output);
    sleep(1);
    $pid = (int) $output[0];

    echo sprintf('%s - Web server started on %s:%d with PID %d', date('r'), $host, $port, $pid) . PHP_EOL;

    // Kill the web server when the process ends
    register_shutdown_function(function() use ($pid) {
            echo sprintf('%s - Killing process with ID %d', date('r'), $pid) . PHP_EOL;
            exec('kill ' . $pid);
        });

    $startUrl = sprintf('http://%s:%s', $host, $port);

Далее значение $startUrl можно использовать в тестах, для определения адреса сервера, на котором запущен проект.

Продуктивного тестирования!


Создано:
Автор:
« Назад на главную

comments powered by Disqus