Debian. Continuous Integration сервер Jenkins для непрерывного тестирования Django-проектов
Сегодня я расскажу как реализовать непрерывное тестирование Django-проекта с помощью Jenkins CI. Мы также будем собирать и выводить разного рода отчеты по тестам, для этого мы установим и настроим дополнительные плагины. Следующие статьи будут о том, как развернуть Jenkins-ноды на FreeBSD, как запустить BDD-тесты с поддержкой Selenium WebDriver через Lettuce и splinter.
В качестве поставщика тестируемого кода будем использовать git, в качестве транспорта для него будем использовать ssh (у меня для этого используется gitolite), адрес сервера будет git.example.org. Адрес сервиса с запущенным Jenkins будет http://jenkins.example.org/.
Ранее, я уже упоминал о Jenkins, там же я говорил о Attlassian Bamboo и Hudson, но для своих проектов я выбрал Jenkins за его простоту, функциональность, количество полезных плагинов и истории-успеха среди Django-проектов. Что касается Hudson, то Jenkins это его форк, о причинах разделения проектов вы можете почитать в статье на хабре.
Кстати, любителям SaaS можно не устанавливать Jenkins, а воспользоваться ShiningPanda.
Терминология
В терминологии Jenkins слово Job и Project это одно и тоже, мы же просто будем называть их "задачами".
Термин Build (далее билд) - это результат выполненой задачи, может находится в трех оконченных состояниях:
SUCCESS (успешный билд, за всю работы задачи небыло ошибок);
FAILED (произошла какая-то ошибка);
ABORTED (билд был прерван по какой-либо причине, в осноновном это - ручное прерывание).
Термином View (а конкретно "List View") обозначается некая страница, на которой перечислены задачи, настраивается она либо выбором через чекбоксы, либо по совпадению по заданному паттерну с именами задач.
В процессе чтения статьи вы встретите переменные окружения:
$JENKINS_HOME - это путь до домашнего каталога Jenkins, скорее всего это "/var/lib/jenkins". Там будут храниться все конфиги Jenkins, задачи, билды и т.д., вообщем всё что относится к Jenkins.
$WORKSPACE - путь до каталога, в котором выполняется задача;
Открываем на редактирование /etc/default/jenkins и добавляем следующие директивы:
# Указываем нужный порт,
# на который далее мы будем проксировать через Nginx
PORT=8090
# Устанавливаем нужную нам кодировку,
# чтобы текст, который попал в stdout (например из тестов) выводился корректно.
# А также устанавливаем нужную таймзону, у меня это UTC
JAVA_ARGS="-Dfile.encoding=UTF8 -Duser.timezone=UTC"
Теперь запустим Jenkins:
sudo service jenkins start
После запуска Jenkins вы можете увидеть текущую кодировку и таймзону в разделе "Manage Jenkins" > "System Information" (прямой адрес http://jenkins.example.com:8090/systemInfo ).
Теперь произведем базовые настройки Jenkins, перейдите в "Manage Jenkins" > "Configure System":
В поле System Admin E-mail Address укажите почту, от которой будут приходить письма от Jenkins, например "jenkins@example.org".
Далее, нам надо настроить отправку уведомлений по почте, переходим в секцию E-mail Notification и настраиваем SMTP:
В поле SMTP server указываем "localhost", либо другой обслуживающий ваш сервер почтовый сервер. Если используете локальный sendmail, то установите его.
В секции Git plugin:
В поле Global Config user.name Value укажите "Jenkins";
В поле Global Config user.email Value укажите "jenkins@example.org".
Настроим проксирование через Nginx
Вот пример конфига для Nginx, работать будем через самописный ssl-сертификат и добавим base-auth:
Если быть точнее, то надо в секцию вашего интерфейса добавить pre-up, но так как чаще всего именно в конце файла определён нужный интерфейс, то рекомендация выше будет верна. Развернутый пример:
Переходим в "Manage Jenkins" > "Manage Plugins" > "Available", выбираем:
GIT plugin, с ним также установится плагин Git Client Plugin - так как мы пользуемся git, то очевидно что надо установить плагин для работы с этой SCM;
Если у вас возникли проблемы с GIT plugin, и его версия 1.3.0, а версия GIT client plugin 1.0.4, то прочитайте комментарии к багу JENKINS-17204, там есть мой комментарий, который вам непременно поможет. А если вкратце, то в новой версии плагина есть баг, и надо просто откатиться на версию назад.
AnsiColor Plugin (форк и более свежий оригинал на GitHub) - с помощью него можно лицезреть цветные логи, которые генерирует ваша программа (например в harvest есть verbose-режим с цветный выводом и т.п.);
В настройках задачи установите чекбокс на Color ANSI Console Output и выберите нужный ANSI color map, у меня это "xterm".
Timestamper - будет выводить текущее время на каждую строчку вывода лога из консоли;
В настройках задачи установите чекбокс на Add timestamps to the Console Output.
xUnit Plugin - если ваши тесты умеют генерировать отчеты в формате xUnit (а Lettuce и django-jenkins это умеют делать), то вы сможете выводить информацию о результатах тестирования в удобном для человека виде (графики и таблицы), например вот так:
Это приложение позволяет упростить процесс интеграции с Jenkins CI, нам оно поможет сгенерировать нужные для нас отчеты. Создайте отдельный "settings" в проекте для него, например project/settings/jenkins.py:
Также, при вызове команды manage.py jenkins можно передать дополнительные опции для указанных в JENKINS_TASKS раннеров, для этого смотрите manage.py jenkins --help.
Теперь установим в проект django-jenkins, а также указынные нами зависимости:
Оригинальный репозиторий проекта находится на GitHub, установить можно с PyPI. Также рекомендую к прочтению туториал.
Добавление и настройка задачи (Job/Project)
Для добавления задачи необходимо нажать на "New Job", выбирать "Build a free-style software project".
В секции "Source Code Management" выбрать чекбокс на "Git Repositories". В "Repository URL" вставляем git@git.example.org:repo-name.git, а в "Branches to build" указываем нужную ветку, например "master".
Теперь настроим "Poll SCM" > "Schedule" (будем каждые 2 минуты проверять изменения в репозитории, если появились изменения, то запускается новый билд):
# Создаем каталог виртуального окружения
virtualenv --no-site-packages --distribute venv
# Сделаем symlink на файл настроек для django_jenkins
ln -fs $WORKSPACE/project/settings/jenkins.py $WORKSPACE/project/local_settings.py
# Устанавливаем зависимости для проекта и тестов
venv/bin/pip install --upgrade -r requirements/base.txt
venv/bin/pip install --upgrade -r requirements/tests.txt
# Запускаем тесты с использованием django_jenkins
venv/bin/python ./manage.py jenkins --verbosity=2 --output-dir=reports
Я обычно это всё выделяю в sh-скрипт и кладу в репозиторий, после чего просто указываю его для вызова.
Теперь вы можете запустить задачу вручную, нажав "Build Now". Либо добавить коммит в репозиторий и через 2 минуты самостоятельно запустится задача.
После запуска тестов у вас должен появится каталог $WORKSPACE/reports, где будут хранится разного рода отчеты (xUnit, pep8, pylint и т.д.).
Бекап Jenkins
Я честно пробовал пользоваться плагином для бекапа thinBackup, но у него есть огромная проблема - он останавливает Jenkins для того чтобы сделать бекап.
В итоге я отказался от него и написал простой скрипт, который бекапит только конфиги от задач, а остальное мне и не надо.
cd /var/lib/jenkins/jobs
for JOB in *; do
BACKUP_JOB_DIR="/var/lib/jenkins/Backups/configs/$JOB"
mkdir -p $BACKUP_JOB_DIR
cp "$JOB/config.xml" "$BACKUP_JOB_DIR/config.xml";
# git commit =am "Autocommit (`hostname`): `date`"
done
Просто создаете еще одну задачу, которая будет переодически бекапить конфиги.
Напоследок
Под строкой поиска находится ссылка ENABLE AUTO REFRESH, нажмите её чтобы автоматически обновлять страницу и сделать Jenkins более интерактивным.
@ALex_hha, для настройки нод использую Credentials, но для настройки гита это неудобно, потому что часто приходится вручну обновлять гит из консоли. Мой вариант закрывает сразу две потребности
Комментарии
Вы рассматривали какие-нибудь альтернативы помимо splinter? Использовать Selenium WebDriver или что-то совершенно другое.
Что для вас было решающим при определении выбора splinter?
splinter это обвязка вокруг селениума и других драйверов, как zope.testbrowser
Я выбрал splinter потому что он мне показался самым удобным и популярным
Как насчет (CasperJS + PhantomJS + GPU)
А сравнительные тесты перформанса где посмотреть?
вы явно делаете что то не так, настройка доступа к git производится на вкладке Credentials
@ALex_hha, для настройки нод использую Credentials, но для настройки гита это неудобно, потому что часто приходится вручну обновлять гит из консоли. Мой вариант закрывает сразу две потребности
Оставьте свой комментарий