Phing and PHPUnit

I started reading up on Jenkins as I want to learn more about it and noticed it has an extension to work with Phing scripts. It’s been a while since I used Phing so I decided to spend some time learning more about its current state. The goal being to create a script that would run various PHP tasks starting with unit tests using PHPUnit. After spending some time, I got it working and decided to document my findings in this post.

All the following code can be found in this github repo:

Getting Our Dependencies

First we want to create a new folder and install composer. Now that you have composer, create a composer.json file with the contents of the file below:

{
    "autoload": {
        "classmap": [
            "src/"
        ]
    },
    "require-dev": {
        "phing/phing": "2.*",
        "phpunit/phpunit": "^8"
    }
}

and run:

php composer.phar install

This will install all you need to work with Phing and PHPUnit for this exercise. Now we want to add some code and tests to verify PHPUnit works. You can write some sample code or copy/paste the classes I created in this github project under src/ and tests/.

PHPUnit

Before we run phpunit, we do want to add a phpunit.xml file and some configuration information so phpunit knows where the tests are and where the autoloader is as well:

<phpunit
    bootstrap="./vendor/autoload.php"
    colors="true">
    <testsuites>
        <testsuite name="Tests">
            <directory>./tests/</directory>
        </testsuite>
    </testsuites>
</phpunit>

Now we can run vendor/bin/phpunit and see all tests pass!

Getting Phing To Work

This part was a bit tricky. I saw in the documentation the PHPUnitTask but I was unable to get it to run any tests. After some research, and I didn’t verify this, it seems the PHPUnit Task is not compatible with the later version of PHPUnit that use namespacing.

Instead of using the PHPUnit Task, I decided to try the ExecTask. That worked well! I just needed to find the right configuration to get Phing to detect the output and if it was a pass or failure. To do this, I used the following settings in the build.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<project name="PhingTests" default="tests">
    <target name="tests">
        <echo msg="Running unit tests" />
        <exec executable="./vendor/bin/phpunit" passthru="true" checkreturn="true" />
        <!-- doesn't seem to work with namespaced versions of phpunit -->
        <!-- <phpunit codecoverage="false" pharlocation="./vendor/bin/phpunit">
            <formatter type="plain" usefile="false"/>
            <batchtest>
                <fileset dir="./tests/">
                    <include name="**/*Test*.php"/>
                </fileset>
            </batchtest>
        </phpunit> -->
    </target>
</project>

Setting passthru and checkreturn lets us capture the results of the execution command and check the return code to see if it was a successful run or a failure. Now, running vendor/bin/phing (which by default calls the tests target) returns the following:

And there you have it, Phing with PHPUnit working! Just for fun, I updated the code to simulate a tests failure to verify the process is working and here is what you get in Phing when PHPUnit fails:

Leave a Reply

Your email address will not be published. Required fields are marked *