Проводим тесты с Selenium без X11

Так как написание тестов с zope.testbrowser иногда может проходить не слишком гладко, не так давно Christian Zagrodnick подсказала мне еще раз взглянуть на Selenium. Selenium запускает предварительно записанные тесты или скрипты со сценарием для тестирования вашего веб-приложения в браузере: например, кликните тут, проверьте присутствуют ли слова ‘hello world’, кликните там и так далее. Это как вести автомобиль, не держа руки на руле.

Сейчас я припоминаю, что уже использовал Selenium раньше, но:

  • Его установка была сплошным расстройством, особенно это касалось работы с Plone TestCase
  • Установить его в непрерывной комплексной среде также составляло непростую задачу.

Мотивация

После начала использования Plone 4, нового компонента контрольных примеров , написание тестов для пакетов Plone стало намного проще. Пакеты gocept.selenium создают для Selenium славную совместимую «упаковку» и предоставляют классы тестов для тестов Zope2, Plone и Zope3. В результате, установка и поддержка тестов с Selenium стали также намного проще.

Единственной недостающей деталью была непрерывная интеграционная среда. Я провожу все тесты всех пакетов, которые я разрабатываю на Mooball в Hudson беспрерывно. Возможность также проводить и все тесты Selenium была бы огромным плюсом. Но, без Х сервера, вы не сможете запустить браузер, который необходим для проведения тестов.

Мне не понравилась идея устанавливать полную X среду на мой CI сервер, поэтому я хорошенько поискал и нашел эти статьи, в которых рассказывается, как проводить тесты с Selenium без необходимости устанавливать полный X сервер:

  • Пакет для тестирования Hudson и Selenium
  • Как: проводить тесты Selenium с Hudson на Headless Linux Server, Часть One–Xvfb

Есть и другие, но именно эти помогли мне начать.

Проблема

Моими основными вопросами были следующие:

  1. Как запустить сервер selenium? Запускать сервер для каждой сборки или оставить его работать как демон в фоновом режиме?
  2. Запускать X сервер (например, Xvfb) или X сервер с VNC сервером, ведь Hudson уже предоставляет плагины для VNC серверов?
  3. Запускать X сервер для сборки или оставить его работать в фоновом режиме?

Мое решение

  1. Сервер Selenium
    Я сконфигурировал сервер Selenium для работы в виде демона. Запуск/остановка сервера для каждого теста были бы слишком ресурсоемкими и скорее всего ненадежными. Так что я сделал небольшой скрипт . Это позволяет мне запустить сервер Selenium в boot time и оставить запущенным.
    ``` #! /bin/bash

    BEGIN INIT INFO

    Provides: selenium-server

    Required-Start: $local_fs $remote_fs $network $named $time

    Required-Stop: $local_fs $remote_fs $network $named $time

    Should-Start: $syslog

    Should-Stop: $syslog

    Default-Start: 2 3 4 5

    Default-Stop: 0 1 6

    Short-Description: Starts selenium server for testing

    Description: Selenium server for functional testing

    END INIT INFO

    . /lib/lsb/init-functions

    SELENIUM=/opt/selenium-server/selenium-server.jar
    BMODE=firefoxchrome
    PORT=4444
    LOG=/opt/selenium-server/selenium.log
    PIDFILE=/opt/selenium-server/selenium.pid
    DISPLAY=:1.0

    pidof_server() {
    if [ -e “$PIDFILE” ]; then
    if pidof java | tr ’ ’ ‘\n’ | grep -w $(cat $PIDFILE); then
    return 0
    fi
    fi
    return 1
    }

    case $1 in
    start)
    DISPLAY=$DISPLAY java -jar $SELENIUM -timeout 180 -singlewindow -port $PORT -forcedBrowserMode $BMODE > $LOG &
    log_daemon_msg “Starting Selenium server!” “selenium-server”
    echo $! > $PIDFILE
    ;;
    stop)
    SELPID=cat $PIDFILE && kill $SELPID
    log_daemon_msg “Stopping Selenium server!” “selenium-server”
    ;;
    status)
    PID=$(pidof_server) || true
    if [ -n “$PID” ]; then
    echo “Selenium Server is running (pid $PID).”
    exit 0
    else
    echo “Selenium Server is NOT running.”
    exit 1
    fi
    ;;
    *)
    log_success_msg “Usage: /etc/init.d/selenium-server {start|stop|status}”
    exit 1
    ;;
    esac

    </li><li><strong>+ 3. X Сервер</strong><br>Я решил устанавливать Xvfb и сначала думал о том, чтобы запускать/останавливать его для каждой сборки, но затем я опять подумал, что это будет неудобно и слишком ненадежно, если сервер, по какой-либо причине не запуститься или даст сбой. Я сделал еще один скрипт, предназначенный для того, чтобы Xvfb оставался запущенным . Примечание: однако, я не блокирую разрешение доступа для соединения с Xvfb, что делают авторы из других блогов.
    

    #! /bin/bash

    BEGIN INIT INFO

    Provides: xvfb-server

    Required-Start: $local_fs $remote_fs $network $named $time

    Required-Stop: $local_fs $remote_fs $network $named $time

    Should-Start: $syslog

    Should-Stop: $syslog

    Default-Start: 2 3 4 5

    Default-Stop: 0 1 6

    Short-Description: Starts xvfb server for testing

    Description: xvfb server for functional testing

    END INIT INFO

    . /lib/lsb/init-functions

    PIDFILE=/opt/xserver/xserver.pid
    DISPLAY=:1.0

    pidof_server() {
    if [ -e “$PIDFILE” ]; then
    if pidof Xvfb | tr ’ ’ ‘\n’ | grep -w $(cat $PIDFILE); then
    return 0
    fi
    fi
    return 1
    }

    case $1 in
    start)
    Xvfb $DISPLAY -screen scrn 1024x768x24 &
    disown
    echo $! > $PIDFILE
    ;;
    stop)
    SELPID=cat $PIDFILE && kill $SELPID
    ;;
    status)
    PID=$(pidof_server) || true
    if [ -n “$PID” ]; then
    echo “Xvfb is running (pid $PID).”
    exit 0
    else
    echo “Xvfb is NOT running.”
    exit 1
    fi
    ;;
    *)
    echo “Usage: xvfb-server.sh {start|stop|status}”
    exit 1
    ;;
    esac

    </li></ol><h2>Установка </h2><p>А сама установка довольно проста:</p><ol><li>Установите  java и selenium (это предпочел я / выбирайте)</li><li>Сконфигурируйте переменные первоначального скрипта (порт, путь, браузер и т.д.). Лично я предпочитаю другим  firefoxchrome, который, как по мне, работает хорошо.</li><li>Установите Xvfb и отладьте переменные первоначального скрипта.</li><li>Запустите оба сервера. Если вы проводите тесты с gocept.selenium, следуйте инструкциям по установке на странице пакетов pypi.</li></ol><p>Вот и все. Любые предложения и обновления приветствуются.</p>

также можно использовать PyVirtualDisplay, обертка на Python для Xvfb и Xephyr.

$ sudo apt-get install xvfb xserver-xephyr python-pip
$ sudo pip install pyvirtualdisplay
#!/usr/bin/env python

from pyvirtualdisplay import Display
from selenium import webdriver

display = Display(visible=0, size=(800, 600))
display.start()

# now Firefox will run in a virtual display. 
# you will not see the browser.
browser = webdriver.Firefox()
browser.get('http://www.google.com')
print browser.title
browser.quit()

display.stop()