Tips on the FLOW3 build system

For the FLOW3 distributions a new build system is on the horizon (under review to be exact), which will be used for the TYPO3 Phoenix distribution (and others) as well. This post shall explain how to use it for some common tasks, like unit and functional testing.

Unit Testing

With the new build system come configuration files for PHPUnit that make it really easy yet flexible to run unit tests for FLOW3 projects. The simplest case of running all unit tests in a distribution takes nothing more than:
phpunit -c Build/Common/PhpUnit/UnitTests.xml

That will run all unit tests found below Packages and show progress in the console. A JUnit compatible XML file is generated in Build/Reports/UnitTests.xml

If you want to generate a code coverage report in HTML, you need to amend the command a little:
phpunit -c Build/Common/PhpUnit/UnitTests.xml --coverage-html Build/Reports/UnitTestsCoverage

After the test run you will find the JUnit XML file as before, but there will also be a nice coverage report in Build/Reports/UnitTestsCoverage/index.html.

If you want to run only a subset of tests, you can specify a path or filter like follows:
phpunit -c Build/Common/PhpUnit/UnitTests.xml Packages/Framework/FLOW3/Tests/Unit/AOPphpunit -c Build/Common/PhpUnit/UnitTests.xml --filter '/\\AOP\\/'

Functional Testing

... is very similar to unit testing, you just need to use the FunctionalTests.xml configuration file instead, the XML report ends up in Build/Reports/FunctionalTests.xml.

You can then use the same filtering and can of course generate code coverage reports. In addition functional testing generates a testdox report in Build/Reports/FunctionalTestDox.txt

Note: for code coverage on all tests you will need to raise your memory limit (for the FLOW3 distribution 512M is too little).

Phing is for automation

Phing is build tool we use for automating tasks like creating release archives and documentation rendering.

Calling Phing follows the same principle:
phing -f Build/Common/Phing/Master.xml [options] [target]

The following introduces some of the more useful tasks we defined.

Cleaning up

The clean target removes temporary files (caches, logs, ...). The polish target removes temporary files as well as any rendered documentation.

Rendering documentation

To render the package manuals from DocBook to HTML and generate API documentation in one go you need to call the render-docs target. The documentation can then be viewed in the documentation viewer as usual.

Running tests

The lint target runs a syntax check on all PHP and JS files (with some exceptions, e.g. ExtJS is not checked).

The PHPUnit way of running tests has been tied to Phing as well, so that the targets test-unit and test-functional do what you expect. The test target runs them both.

Note that using Phing to run the tests does not allow to filter the tests and will not generate code coverage data. You can generate a HTML report for the test results themselves, though:
phing -f Build/Common/Phing/Master.xml -DhtmlReport test

The reports will be in Build/Reports/UnitTests/index.html and Build/Reports/FunctionalTests/index.html respectively.

Metrics generation

The metrics target collects code metrics and reports to Build/Reports/CopyPasteDetection.xml and Build/Reports/ProjectMessDetection.xml.

For manual use direct use of the phpcpd and phpmd commands might be an alternative (not everyone reads XML reports by heart), though.

There is more to it...

This is probably the most useful stuff. There are more targets defined and also some extension points for adding custom targets are in place. That will be covered some other day...

1 comment:

M Butcher said...

It's interesting to read about the build details of Flow3.

I'm a huge Phing fan because it simplifies the management of packages large and small. I found it useful to create multiple testing reports in Phing so that my development went faster.

I created a 'fasttest' target that linted and ran a quick text-only unit test, and then only displaying a message saying whether or not the tests passed. I bound that as a shortcut in my editor (TextMate) and then just got in the habit of running it every so often.

I also created a target for coverage reports, which Phing also does quite nicely. Having that as a quick task makes me at least somewhat more likely to make sure that I am adequately testing my project.

Oh, I also found that adding a doxygen task was pretty useful. What was nice about that was that I could use some of Phing's replacement tasks to update documentation values just-in-time (things like version strings and dates).

Sorry, I know I'm drifting to the margins of the topic. But I'm tremendously interested in how PHP projects can be managed more efficiently.