13 февраля 2013 г.

Jenkins для PHP на Windows или улучшенное автотестирование Selenium при коммитах (ч1)

Возможно, вам так же будет интересна статья Установка и настройка Jenkins + Vagrant + Selenium с нуля на Linux (Debian).

В этой статье я запишу свой опыт настройки системы непрерывной интеграции Jenkins для PHP-проекта в Windows. Статьи об этом не редкость: раз, два. Но я расскажу о проблемах, решение которых не было описано сразу в одном месте, но которые мне удалось решить, собрав информацию по кусочкам.

Цель: собрать систему, которая в автоматическом режиме при изменении кода (коммите и выполненном выталкивании), либо вручную будет производить следующие операции:
  • сборка проекта, например, css, js-файлов - выполнение произвольных скриптов;
  • проверка на ошибки синтаксиса - использование lint;
  • посчитать количество строк, классов, методов, функций, файлов, строк комментариев и прочее - phploc;
  • посчитать метрики - pdepend;
  • проанализировать качество кода по нескольким правилам - phpmd;
  • найти участки одинакового кода - phpcpd;
  • выполнить модульное тестирование - phpunit;
  • выполнить Selenium-тестирование с использованием удалённого Selenium-сервера;
  • собрать логи всех операций, сосчитать количество ошибок/предупреждений и на основе настройки порогов значение присвоить статус успешности билда;
  • оповестить всех разработчиков / последних коммитивших об изменении статуса билда;
  • автоматическое развертывание (deployment), если нужно. 

Общая информация о PHP и Jenkins находится здесь http://jenkins-php.org/.
Рассмотрим подробнее.


1. PEAR и его пакеты

Указанные выше программы (phploc, pdepend и другие) распространяются в пакетах PEAR.
Установим PEAR:
Скачиваем http://pear.php.net/go-pear.phar и размещаем его рядом с php.exe, находясь командной строкой в директории с php.exe, выполняем команду
php go-pear.phar
Будут заданы некоторые вопросы. Я устанавливал локальную копию, пути оставил по умолчанию. Установка PEAR подразумевает изменение php.ini, а именно добавляет в include_path путь до установленного PEAR. После этого нужно перезапустить веб-сервер.
Если в директории с php.exe появился pear.bat, то скорее всего PEAR установился.

Установка пакетов:
Выполняем команду
pear config-set auto_discover 1
если в ответ получили ошибку доступа, то командную строку нужно запустить от имени администратора и повторить команду.
Далее
pear install pear.phpqatools.org/phpqatools
Если операция пройдет успешно, то рядом с php.exe появятся .bat-файлы инструментов.
Установка PEAR-пакетов для меня почти всегда создает проблемы, но их разбор здесь не рассматривается.
Важно, чтобы путь до php.exe был прописан в PATH для того, чтобы установленные утилиты были доступны из любой директории.

2. Jenkins как служба Windows

Скачиваем native-пакет для Windows с официального сайта. Разархивируем. Используем setup.exe для установки. Для работы Jenkins требуется JDK. Jenkins имеет веб-интерфейс, по умолчанию занимает порт 8080 и доступен по адресу http://localhost:8080/ в случае успешной установки. Если служба не стартует, убедитесь что порт 8080 не занят другой программой.

3. Ant и build.xml

Ant - утилита для сборки проектов по описанному сценарию. Скачиваем zip-архив с официального сайта и распаковываем его в любое место, например,
D:\WebServer\apache-ant-1.8.4
Прописываем путь к ant.bat в переменную окружение PATH (у меня D:\WebServer\apache-ant-1.8.4\bin). Теперь после открытия командной строки и ввода
ant.bat
в ответ должно быть сообщение о не найденном файле build.xml (если, конечно, в текущем каталоге такой файл случайно не нашелся).

Файл build.xml является сценарием для сборки проекта и должен находится в корне вашего php-проекта. Сайт jenkins-php.org предлагает заготовку этого файла
http://jenkins-php.org/download/build.xml 
Сам файл содержит строки с целями (target) - инструкциями. Первая цель в этом файле называется build и она зависит (depends) от других целей, которые будут выполнены.
Это и есть шаги сборки. Почти каждая цель в этом файле содержит exec - исполнение какого-либо скрипта или приложения с параметрами (arg).
Важно: для Windows нужно поменять значения всех executable (кроме php), дописав в конце .bat, например, phploc.bat, phpmd-ci.bat.
Для начала попробуйте убрать в depends самой первой цели всё, кроме lint:
<target name="build" depends="lint"/>
Затем с помощью командной строки перейдите в директорию с проектом и выполните команду
ant.bat
 От этого должна запуститься проверка синтаксиса. Если она началась, то можно вернуть остальные шаги и зафиксировать изменение в системе контроля версий.

4. Jenkins job for PHP

Job (задача) в системе Jenkins - это настройки проекта, в котором указаны условия сборки, шаги для выполнение сборки, анализ результатов, действия по завершению сборки.
Сайт jenkins-php.org предлагает шаблон job для PHP-проектов. Шаблон требует установки плагинов для Jenkins, которые будут обрабатывать результаты, полученные при сборке проекта с помощью ant.

Установка плагинов описана на сайте http://jenkins-php.org/ я продублирую её.
Список плагинов для установки:
Дополнительно я установил плагин для Merucrial.
Установить их можно либо из веб-панели по адресу
http://localhost:8080/pluginManager/available
либо используя Jenkins CLI:
1. Скачиваем утилиту из установленного Jenkins
http://localhost:8080/jnlpJars/jenkins-cli.jar
2. Запускаем её, указав, что хотим установить
java -jar jenkins-cli.jar -s http://localhost:8080 install-plugin checkstyle cloverphp dry htmlpublisher jdepend plot pmd violations xunit
3. Перезапускаем службу
java -jar jenkins-cli.jar -s http://localhost:8080 safe-restart

Установка php-template:
1. Создаем пустую директорию с именем php-template в
<путь до Jenkins>/jobs
2. Скачиваем в только что созданную директорию файл-шаблон config.xml
Должно получиться с учетом возможности отличия путей:
C:\Program Files\Jenkins\jobs\php-template\config.xml
3. Перезагружаем Jenkins через веб-интерфейс или через ранее описанную Jenkins CLI:
java -jar jenkins-cli.jar -s http://localhost:8080 reload-configuration
Создание задачи на основе шаблона для вашего php-проекта.
1. Зайдите в веб-панель Jenkins по адресу
http://localhost:8080/
2. Слева вверху нажмите "Новая задача".
3. Введите имя проекта, затем выберите последнюю опцию для копирования задачи из существующей, введите в поля рядом "php-template" и нажмите ОК.
4. Снимите галочку с "Приостановить сборки"
5. Заполните данные для секции управление исходным кодом. У себя я заполнил URL для моего Mercurial репозитория (предварительно установив плагин для Mercurial).
6. Заполните триггеры сборки. Для себя я указал "Опрашивать SCM об изменениях" с расписанием каждые 15 минут:
*/15 * * * *
7. Нажмите сохранить.

Теперь когда проект настроен, его можно собрать. Нажмите кнопку слева в меню "Собрать сейчас". Через пару секунд под меню в очереди сборки появится ссылка на сборку. Кликнете по ней, затем нажмите "Вывод консоли". Там будет виден ход выполнение и возникающие ошибки. Если сборка пройдет успешно, будут видны различные диаграммы с результатами анализа. Но если phpunit не сконфигурирован, то сборка не будет успешной.

5. Настройка PHPUnit

Цель в build.xml записана так
 <target name="phpunit" description="Run unit tests with PHPUnit">
    <exec executable="phpunit.bat" failonerror="true"/>
 </target>
Так как здесь не указаны аргументы, то phpunit будет искать настройки в корни проекта в файле phpunit.xml или phpunit.xml.dist.
Мой phpunit.xml.dist. содержит следующие настройки:
<?xml version="1.0" encoding="UTF-8"?>

<phpunit bootstrap="tests/Bootstrap.php"
         backupGlobals="false"
         backupStaticAttributes="false"
         strict="true"
         verbose="true">

  <testsuites>
    <testsuite name="Portal">
      <directory suffix="Test.php">tests/src</directory>
    </testsuite>
  </testsuites>

  <logging>
    <log type="coverage-html" target="build/coverage" title="BankAccount"
         charset="UTF-8" yui="true" highlight="true"
         lowUpperBound="35" highLowerBound="70"/>
    <log type="coverage-clover" target="build/logs/clover.xml"/>
    <log type="junit" target="build/logs/junit.xml" logIncompleteSkipped="false"/>
  </logging>

  <filter>
    <whitelist addUncoveredFilesFromWhitelist="true">
      <directory suffix=".php">src</directory>
    </whitelist>
    <blacklist>
       <directory suffix=".php">src/Smarty</directory>
    </blacklist>
  </filter>

</phpunit>
Для phpunit у меня указан Bootstrap класс, в котором можно указать предварительные настройки тестового окружения. У меня он содержит всего пару строк:
<?php
define('APPLICATION_ENV', 'testing');
Для того, чтобы производить анализ покрытия кода тестами, в конфигурации phpunit должна быть настроена секция logging, как в примере выше. С помощью filter можно исключить директории из анализа покрытия тестами. Подробную информацию о файле настроек можно прочитать на сайте phpunit. Следует отметить, что можно обойтись и без файла конфигурации, а указать параметры в build.xml аргументами к запуску phpunit, но не все параметры можно указать таким способом.

6. Запуск Selenium-тестов через PHPUnit

Этот пункт получился объёмным, поэтому я вынес его в отдельную статью.

1 комментарий:

  1. при установке Ant может возникнуть следующая ошибка:
    Unable to locate tools.jar. Expected to find it in ...

    Решается с помощью http://stackoverflow.com/a/10519763

    ОтветитьУдалить