Continuous Integration: Hudson + PHPUnit
There is a chain in the brain: we will write unit tests, then these tests will tell us if we broke something, then they will send us mail that the project has failed.
This is nothing more than an illustration of continuous integration (Continious Integration) is nowhere near the extremely fashionable direction of agile development. The only missing element of the chain is “HOW”. Below is a short recipe, as if answering "very simple."
As part of the recipe, I will not consider how to install hudson, how to write tests in phpunit. All of this is accessible and conveniently described in the respective manuals, and other hub posts.
I can only say that Hudson was chosen afterwards, that it is quite functional, popular and free.
1. Written tests for PHPUnit and assembled into a finished Suite file, let's call it All.php
2. Installed PHPUnit, which can be called from the command line
3. Installed Hudson, and a job has been added for our project
1. Specify the path to the repository in the Source Code Management section. Hudson supports svn, git and cvs
2. We specify the schedule of assemblies \ checks with a cron line in the Build Triggers section.
3. In the Build section indicate the call of our tests
4. In the Post-build Actions section, set the checkbox for Public JUnit test result report, and in the test report XMLs, specify phpunit.xml
5. In the same Post-build Actions section, set the checkbox for E-mail Notification. Specify recipients separated by spaces in the recipients line. And we put the checkbox on Send e-mail for every unstable build
If everything was quite simple, then at this step we could have finished, but, unfortunately, the format in which phpunit provides the results, and the one that hudson expects is a bit are different. Hudson does not understand that there may be several nested suites. And it produces this error: None of the test reports contained any result. Therefore, a tambourine is required.
The idea is simple xml, which phpUnit generates, convert to xml, which is needed for hudson.
To do this, I wrote this script that will do the job for us
6. Add this script to yourself under svn and enter another action in the build section
7. Change in the Junit Test report XMLs from phpunit.xml to test.xml
That's all, look at the beautiful graphs of the tests performed, and get emails if any of the tests went down.
I hope this article will help those who wanted to integrate continious integration into their php development, but thought it was too complicated
This is nothing more than an illustration of continuous integration (Continious Integration) is nowhere near the extremely fashionable direction of agile development. The only missing element of the chain is “HOW”. Below is a short recipe, as if answering "very simple."
As part of the recipe, I will not consider how to install hudson, how to write tests in phpunit. All of this is accessible and conveniently described in the respective manuals, and other hub posts.
I can only say that Hudson was chosen afterwards, that it is quite functional, popular and free.
Ingredients
1. Written tests for PHPUnit and assembled into a finished Suite file, let's call it All.php
2. Installed PHPUnit, which can be called from the command line
3. Installed Hudson, and a job has been added for our project
Recipe
1. Specify the path to the repository in the Source Code Management section. Hudson supports svn, git and cvs
2. We specify the schedule of assemblies \ checks with a cron line in the Build Triggers section.
3. In the Build section indicate the call of our tests
phpunit --log-junit $WORKSPACE/phpunit.xml AllSuite $WORKSPACE/tests/All.php
4. In the Post-build Actions section, set the checkbox for Public JUnit test result report, and in the test report XMLs, specify phpunit.xml
5. In the same Post-build Actions section, set the checkbox for E-mail Notification. Specify recipients separated by spaces in the recipients line. And we put the checkbox on Send e-mail for every unstable build
If everything was quite simple, then at this step we could have finished, but, unfortunately, the format in which phpunit provides the results, and the one that hudson expects is a bit are different. Hudson does not understand that there may be several nested suites. And it produces this error: None of the test reports contained any result. Therefore, a tambourine is required.
The idea is simple xml, which phpUnit generates, convert to xml, which is needed for hudson.
To do this, I wrote this script that will do the job for us
- 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 = "
\n"; - $xmlHudson .= '
- $xmlHudson .='failures="'.$this->countFailures.'" ';
- $xmlHudson .='errors="'.$this->countErrors.'" ';
- $xmlHudson .='time="'.$this->countTime.'">'."\n";
- foreach ($this->cases as $case) {
- $xmlHudson .= $case->asXML()."\n";
- }
- $xmlHudson .= "";
-
- return $xmlHudson;
- }
- }
6. Add this script to yourself under svn and enter another action in the build section
php -f $WORKSPACE/tests/phpunit2hudson.php -- $WORKSPACE/phpunit.xml $WORKSPACE/test.xml
7. Change in the Junit Test report XMLs from phpunit.xml to test.xml
That's all, look at the beautiful graphs of the tests performed, and get emails if any of the tests went down.
I hope this article will help those who wanted to integrate continious integration into their php development, but thought it was too complicated