Friday, September 18, 2009

What's new in PHPUnit 3.4

PHPUnit is the leader testing tool in the php world: the equivalent of JUnit for Java and it's what comes to mind when you're thinking of testing a php application.
Although the Api for PHPUnit 3 is stable, some useful improvements and functionalities have been developed for the 3.4 branch, which has seen its first official release two days ago.

If you have a Pear-based installation, it's very easy to get PHPUnit 3.4. Simply run:
# pear upgrade phpunit/PHPUnit
as root or preceded by sudo.
For some important features, you can refer to the official manual, that is currently in the process of being updated.

Here's a list of some novelties that I have experimented this morning on NakedPhp:
  • test methods dependencies: mark with @depends a test method, followed by the name of the test method which it relies upon. For instance, a test method for deletion of an object in a container depends upon the addition test; this way if the first fails the dependent tests will be automatically skipped and you will locate the bug instantly. Moreover, you can pass fixture from the testAdd() method to testDelete(), effectively reusing it. Keep in mind, however, that this feature works on test methods and not between different test cases.
  • annotations @runTestsInSeparateProcesses and @runInSeparateProcess allow tests running in parallel. They should be used on the test case class and on the test method respectively. However, I've had trouble adding them because some kind of recursive dependency is raised when exporting global variables and xdebug stop it mercilessly.
  • setUpBeforeClass() and tearDownBeforeClass() a la junit have been introduced. Heavy fixture set up now can be done one time per test case.
  • getMockForAbstractClass() will fill in the abstract methods for you.
  • assertStringStartsWith() and assertStringEndsWith() have been added for rapid assertions.
  • PHPUnit_Extensions_TicketListener_Trac can open and close Trac tickets basing on a test result: I think the @ticket annotation is stricly related to this component. I have not yet tried it since I do not have a Trac instance available (and I think this process can be slow), but it seems a good step forward to expose brittle tests. Especially if used in continuos integration.
  • Mock Objects can now be passed to with() without issues. The cloning problems for with() can be though to resolve since objects are cloned when passed to with() to allow assertions being run on them after the test method has returned: obviously asserting that an object is identical to an expected one would never work, and asserting simple equality is often worse since very big objects can be passed around and duplicated.
  • You can mock namespaced classes (in php 5.3) without going to a complicated process to autoload them first and then specify all the parameters to getMock(). Good!
  • @covers annotation support has been extended to setUp() and tearDown(), and the relative code coverage calculation has been improved.
These are the most important features that I have found in the ChangeLog and I have already tried to experiment a few of them them personally in my projects. Feel free to add your discoveries in the comments.

No comments: