Chapter 3. Continuous Integration

In this chapter we will expand our existing build.xml script for Ant to run unit tests using PHPUnit and then create a Jenkins job for our PHP project.

Instead of putting this information into the build.xml script for Ant, we follow the concept of Separation of Concerns and use PHPUnit's configuration file feature to configure the tests we want to run, the logfiles (JUnit XML for test results and Clover XML for code coverage information) and reports (code coverage report in HTML format) we want generated, and other settings such as the bootstrap script (our autoloader).

Example 3-1 shows the phpunit.xml.dist configuration file for our project.

Invoking phpunit without any parameters in the project directory (where the phpunit.xml.dist configuration file resides) will result in PHPUnit running the tests the way we set it up in the configuration.

We can now add a target to our build.xml script that invokes PHPUnit to run our unit tests. While we are at it, we add two other targets that handle cleaning up build artifacts and preparing directories for build artifacts, respectively:

Example 3-2 shows how these three new targets are implemented. The implementation of the phpab task remains the same as shown in Chapter 1 and is not repeated here.

Example 3-3 shows the output of running the build.xml script with Ant.

We should make sure that the PHP code does not contain an syntax errors before we try to run the unit tests. The code below implements a target that uses Apache Ant's <apply> task to invoke PHP's lint checker (php -l) for each source code file in the src and tests directories. The <apply> task works like the <exec> task but can operate on multiple files when provided with a <fileset>.

<target name="lint">
 <apply executable="php" failonerror="true">
  <arg value="-l" />

  <fileset dir="${basedir}/src">
   <include name="**/*.php" />
  </fileset>

  <fileset dir="${basedir}/tests">
   <include name="**/*.php" />
  </fileset>
 </apply>
</target>

Now we have everything in place to create a job for our PHP project in Jenkins.