Существует цепочка в мозгу: мы напишем юнит тесты, затем эти тесты нам расскажут если мы что-то сломали, затем они нам почту будут отправлять о том, что проект поломался.
Это ничто иное, как иллюстрация непрерывной интеграции (Continious Integration) нычне крайне модного направления гибкой разработки. Единственный недостающий элемент цепочки — «КАК». Ниже коротенький рецепт, как бы отвечающий «очень просто».
В рамках рецепта я не буду рассматривать как поставить hudson, как написать тесты на phpunit. Все это доступно и удобно описано в соответствующих мануалах, и других хабрапостах.
Скажу только, что Hudson выбран потом, что он достаточно функционален, популярен и бесплатен.
1. Написанные тесты на PHPUnit и собранные в готовый Suite файл, назовем его All.php
2. Установленный PHPUnit, который можно вызвать из командной строки
3. Установленный Hudson, и добавлен job для нашего проекта
1. Указываем путь к репозиторию в разделе Source Code Management. Hudson поддерживает svn, git и cvs
2. Указываем расписание сборок\проверок cron строкой в разделе Build Triggers.
3. В разделе Build указываем вызов наших тестов
4. В разделе Post-build Actions ставим checkbox для Public JUnit test result report, а в Test report XMLs указываем phpunit.xml
5. В том же разделе Post-build Actions ставим checkbox для E-mail Notification. Указываем получателей через пробел в строке recipients. И ставим checkbox на Send e-mail for every unstable build
Если бы всё было совсем просто, то на этом шаге можно было бы и закончить, но, к сожалению, формат, в котором phpunit предоставляет результаты, и тот, которого ожидает hudson, немного отличаются. Hudson не понимает того, что может быть несколько вложенных Suite. И выдает вот такое ошибку: None of the test reports contained any result. Поэтому требуется бубен.
Идея проста xml, который генерит phpUnit, конвертировать в xml, который нужен для hudson.
Для этого я написал вот такой скрипт, который и выполнит для нас эту работу
6. Добавляем себе этот скрипт под svn и в раздел build вписываем еще одно действие
7. Меняем в Junit Test report XMLs c phpunit.xml на test.xml
Вот и всё, смотрим на красивые графики выполненных тестов, и получаем емейлы, если какой-то из тестов лёг.
Надеюсь, что данная статья поможет тем, кто хотел внедрить continious integration в свою php разработку, но думал, что это слишком сложно
Это ничто иное, как иллюстрация непрерывной интеграции (Continious Integration) нычне крайне модного направления гибкой разработки. Единственный недостающий элемент цепочки — «КАК». Ниже коротенький рецепт, как бы отвечающий «очень просто».
В рамках рецепта я не буду рассматривать как поставить hudson, как написать тесты на phpunit. Все это доступно и удобно описано в соответствующих мануалах, и других хабрапостах.
Скажу только, что Hudson выбран потом, что он достаточно функционален, популярен и бесплатен.
Ингредиенты
1. Написанные тесты на PHPUnit и собранные в готовый Suite файл, назовем его All.php
2. Установленный PHPUnit, который можно вызвать из командной строки
3. Установленный Hudson, и добавлен job для нашего проекта
Рецепт
1. Указываем путь к репозиторию в разделе Source Code Management. Hudson поддерживает svn, git и cvs
2. Указываем расписание сборок\проверок cron строкой в разделе Build Triggers.
3. В разделе Build указываем вызов наших тестов
phpunit --log-junit $WORKSPACE/phpunit.xml AllSuite $WORKSPACE/tests/All.php
4. В разделе Post-build Actions ставим checkbox для Public JUnit test result report, а в Test report XMLs указываем phpunit.xml
5. В том же разделе Post-build Actions ставим checkbox для E-mail Notification. Указываем получателей через пробел в строке recipients. И ставим checkbox на Send e-mail for every unstable build
Если бы всё было совсем просто, то на этом шаге можно было бы и закончить, но, к сожалению, формат, в котором phpunit предоставляет результаты, и тот, которого ожидает hudson, немного отличаются. Hudson не понимает того, что может быть несколько вложенных Suite. И выдает вот такое ошибку: None of the test reports contained any result. Поэтому требуется бубен.
Идея проста xml, который генерит phpUnit, конвертировать в xml, который нужен для hudson.
Для этого я написал вот такой скрипт, который и выполнит для нас эту работу
- <?php
- if ($_SERVER['argv'][1] || $_GET['unit']) {
-
- $fileUnit = $_SERVER['argv'][1] ? $_SERVER['argv'][1] : $_GET['unit'];
- $fileHudson = $_SERVER['argv'][2] ? $_SERVER['argv'][2] : $_GET['hudson'];
-
- if (file_exists($fileUnit)) {
- new PHPUnit2Hudson($fileUnit, $fileHudson);
- } else {
- die('phpunit xml file not exists '. $file);
- }
-
- } else {
- die("determine file. use command: php -f phpunit2hudson.php -- phpunit.xml hudson.xml");
- }
-
- class PHPUnit2Hudson {
-
- private $xml;
- private $cases = array();
-
- private $countAssertions = 0;
- private $countFailures = 0;
- private $countErrors = 0;
- private $countTime = 0;
-
- function __construct($fileUnit, $fileHudson) {
-
- $oldLevel = error_reporting(0);
- $this->xml = simplexml_load_file($fileUnit);
- error_reporting($oldLevel);
-
- if (!$this->xml->testsuite)
- die('invalid phpunit xml file');
-
- foreach($this->xml->testsuite->attributes() as $key => $value) {
- if ($key == 'failures') $this->countFailures = intval($value);
- if ($key == 'errors') $this->countErrors = intval($value);
- if ($key == 'time') $this->countTime = floatval($value);
- if ($key == 'assertions') $this->countAssertions = intval($value);
- }
-
- $this->getCases($this->xml);
-
- file_put_contents($fileHudson, $this->composeHudson());
- }
-
- function getCases(SimpleXMLElement $node) {
- if (isset($node->testcase))
- foreach ($node->testcase as $case) {
- $this->cases[] = $case;
- } elseif (isset($node->testsuite))
- foreach ($node->testsuite as $suite) {
- $this->getCases($suite);
- }
- }
-
- function composeHudson() {
- $xmlHudson = "<testsuites>\n";
- $xmlHudson .= '<testsuite name="Hudson_Suite" file="All.php" tests="'.sizeof($this->cases);
- $xmlHudson .='" assertions="'.$this->countAssertions.'" ';
- $xmlHudson .='failures="'.$this->countFailures.'" ';
- $xmlHudson .='errors="'.$this->countErrors.'" ';
- $xmlHudson .='time="'.$this->countTime.'">'."\n";
- foreach ($this->cases as $case) {
- $xmlHudson .= $case->asXML()."\n";
- }
- $xmlHudson .= "</testsuite></testsuites>";
-
- return $xmlHudson;
- }
- }
6. Добавляем себе этот скрипт под svn и в раздел build вписываем еще одно действие
php -f $WORKSPACE/tests/phpunit2hudson.php -- $WORKSPACE/phpunit.xml $WORKSPACE/test.xml
7. Меняем в Junit Test report XMLs c phpunit.xml на test.xml
Вот и всё, смотрим на красивые графики выполненных тестов, и получаем емейлы, если какой-то из тестов лёг.
Надеюсь, что данная статья поможет тем, кто хотел внедрить continious integration в свою php разработку, но думал, что это слишком сложно