Phing (PHing Is Not GNU make) is a project build system based on Apache Ant. In the context of PHP, where you do not need to build and compile your sources, the intention of Phing is to ease the packaging, deployment, and testing of applications. For these tasks, Phing provides numerous out-of-the-box operation modules ("tasks") and an easy-to-use, object-oriented model for adding your own custom tasks.
Phing can be installed using the PEAR Installer, as shown in the following command line:
pear install http://phing.info/pear/phing-2.1.0-pear.tgz
Phing uses simple XML build files that specify a target tree where
various tasks get executed. One of the out-of-the-box tasks that comes
with Phing is the <phpunit2>
task that
runs test cases using the PHPUnit framework. It is a functional port of
Apache Ant's JUnit task.
Example 12.1 shows a Phing
build.xml
file that specifies a
<project>
named "BankAccount". The
project's default <target>
is called
test. Using the <phpunit2>
task, this target runs all test cases that can be found in source files
that match the *Test.php
condition. This is done by
using a <batchtest>
element that collects
the included files from any number of nested <fileset>
elements. In this example, the tests declared in the class
BankAccountTest
in the source file
BankAccountTest.php
will be run.
Example 12.1: Phing build.xml file for the BankAccount tests
<?xml version="1.0"?>
<project name="BankAccount" basedir="." default="test">
<target name="test">
<phpunit2 haltonfailure="true" printsummary="true">
<batchtest>
<fileset dir=".">
<include name="*Test.php"/>
</fileset>
</batchtest>
</phpunit2>
</target>
</project>
Invoking Phing in the directory that contains build.xml
(Example 12.1),
BankAccount.php
(Example 8.3),
and BankAccountTest.php
(Example 8.1)
will run the tests by executing the project's default target,
tests:
phing
Buildfile: /home/sb/build.xml
BankAccount > test:
[phpunit2] Tests run: 4, Failures: 0, Errors: 0, Time elapsed: 0.00067 sec
BUILD FINISHED
Total time: 0.0960 seconds
Table 12.1 shows the parameters that
can be used to configure the <phpunit2>
task.
Table 12.1. Attributes for the <phpunit2> element
Name | Type | Description | Default |
---|---|---|---|
haltonerror | Boolean | Stops the build process if an error occurs during the test run. | false |
haltonfailure | Boolean | Stops the build process if a test fails. Errors are considered failures as well. | false |
printsummary | Boolean | Prints one-line statistics for each test case. | false |
The following example shows the
<phpunit2>
task's output when a test
fails:
phing
Buildfile: /home/sb/build.xml
BankAccount > test:
[phpunit2] Tests run: 4, Failures: 1, Errors: 0, Time elapsed: 0.00067 sec
Execution of target "test" failed for the following reason:
/home/sb/build.xml:5:37: One or more tests failed
BUILD FAILED
/home/sb/build.xml:5:37: One or more tests failed
Total time: 0.0968 seconds
Besides the required <batchtest>
element,
the <phpunit2>
element allows for
another nested element: <formatter>
is
used to write test results in different formats. Output will always be
sent to a file, unless you set the usefile
attribute
to false
. The name of the file is predetermined by
the formatter and can be changed by the outfile
attribute. There are three predefined formatters:
brief
Prints detailed information in plain text only for test cases that failed.
plain
Prints one-line statistics in plain text for all test cases.
xml
Writes the test results in XML format.
Table 12.2 shows the
parameters that can be used to configure the
<formatter>
task.
Table 12.2. Attributes for the <formatter> element
Name | Type | Description | Default |
---|---|---|---|
type | String | Use a predefined formatter (xml, plain, or brief). | |
classname | String | Name of a custom formatter class. | |
usefile | Boolean | Determines whether output should be sent to a file. | true |
todir | String | Directory the file is written to. | |
outfile | String | Name of the file that is written to. | Depends on the formatter used. |
To generate a test report in HTML format, you can use the
<phpunit2report>
task, which applies an
XSLT stylesheet to the XML logfile created by the
<formatter>
task. Phing ships with two
XSLT stylesheets -- phpunit2-frames.xsl
and
phpunit2-noframes.xsl
-- that generate HTML reports
with or without frames, respectively.
Example 12.2 shows
a build.xml
file for Phing that runs the tests from
the BankAccountTest
class and generates a test report
in HTML format using the phpunit2-frames.xsl
XSLT
stylesheet. The HTML files generated for the report will be written to
the report/
directory that is created by the
prepare <target>
and
deleted by the clean
<target>
.
Example 12.2: Applying an XSLT stylesheet to get a test report
<?xml version="1.0"?>
<project name="BankAccount" basedir="." default="report">
<target name="prepare">
<mkdir dir="report"/>
</target>
<target name="clean">
<delete dir="report"/>
</target>
<target name="report" depends="prepare">
<phpunit2>
<batchtest>
<fileset dir=".">
<include name="*Test.php"/>
</fileset>
</batchtest>
<formatter type="xml" todir="report" outfile="logfile.xml"/>
</phpunit2>
<phpunit2report infile="report/logfile.xml" format="frames" styledir="." todir="report"/>
</target>
</project>
The following example shows the output of the phing
command as it runs:
phing
Buildfile: /home/sb/build.xml
BankAccount > prepare:
[mkdir] Created dir: /home/sb/report
BankAccount > report:
BUILD FINISHED
Total time: 0.1112 seconds
Figure 12.1 shows the title page of the generated test report.
Table 12.3 shows
the parameters that can be used to configure the
<phpunit2report>
task.
Table 12.3. Attributes for the <phpunit2report> element
Name | Type | Description | Default |
---|---|---|---|
infile | String | The filename of the XML results file to use. | testsuites.xml |
format | String | The format of the generated report. Must be frames or noframes . | noframes |
styledir | String | The directory where the stylesheets are located. The stylesheets must conform to the following conventions: the stylesheet for the frames format must be named phpunit2-frames.xsl , the stylesheet for the noframes format must be named phpunit2-noframes.xsl . | |
todir | String | The directory where the files resulting from the transformation should be written to. |
In addition to the test report that we just generated, Phing can
generate a code-coverage report. For this, we need the
<coverage-setup>
and
<coverage-report>
tasks. The former
prepares a database in which code-coverage information is stored while
the tests are run; the latter formats such a database into a report in
HTML format using XSLT stylesheets.
Example 12.3 shows
a build.xml
file for Phing that runs the tests from
the BankAccountTest
class and generates a
code-coverage report in HTML format.
Example 12.3: Generating a code-coverage report
<?xml version="1.0"?>
<project name="BankAccount" basedir="." default="coverage-report">
<target name="prepare">
<mkdir dir="coverage-report"/>
</target>
<target name="clean">
<delete dir="coverage-report"/>
</target>
<target name="coverage-report" depends="prepare">
<coverage-setup database="./coverage-report/database">
<fileset dir=".">
<include name="*.php"/>
<exclude name="*Test.php"/>
</fileset>
</coverage-setup>
<phpunit2>
<batchtest>
<fileset dir=".">
<include name="*Test.php"/>
</fileset>
</batchtest>
</phpunit2>
<coverage-report outfile="coverage-report/coverage.xml">
<report todir="coverage-report" styledir="."/>
</coverage-report>
</target>
</project>
Figure 12.2 shows the title page of the generated code-coverage report.