PHPUnit 4.0: Code Coverage Improvements

Sebastian Bergmann |

One of the highlights of PHPUnit 4.0, which was released last week, is an improvement of the @covers annotation and the addition of the @uses annotation for better code coverage analysis.

Denoting which unit(s) of code a test covers

Earlier versions of PHPUnit already supported the @covers annotation to denote which unit(s) of code a test wants to cover:

1 2 3 4 5 6 7 8
<?php
class   BankAccount
{
     public   function   deposit ( Money   $money )
     {
         // ...
     }
}

1 2 3 4 5 6 7 8 9 10 11
<?php
class   BankAccountTest   extends   PHPUnit_Framework_TestCase
{
     /**
     * @covers BankAccount::deposit
     */
     public   function   testMoneyCanBeDepositedInAccount ( )
     {
         // ...
     }
}

When the @covers annotation is used, any code coverage for code that is not specified using a @covers annotation but executed during the test is discarded. This way only code that is actually tested will be marked as being covered by a test in the code coverage report.

Dealing with unintentionally covered code

PHPUnit 4.0 can optionally be strict about unintentionally covered code (strict coverage mode). When enabled, PHPUnit will fail a test that uses the @covers annotation and executes code that is not specified using a @covers annotation.

Introducing the @uses annotation

Being strict about the covered code leads to a problem when the unit of code under test uses a value object (which does not make sense to stub) as this object, too, would need to be listed using the @covers annotation in order for the test to succeed. Listing the value object using the @covers annotation, however, leads to false code coverage for the value object's code as it is not actually tested in this test.

To solve this problem, a new annotation, @uses, has been be added:

1 2 3 4 5 6 7 8 9 10 11 12
<?php
class   BankAccountTest   extends   PHPUnit_Framework_TestCase
{
     /**
     * @covers BankAccount::deposit
     * @uses   Money
     */
     public   function   testMoneyCanBeDepositedInAccount ( )
     {
         // ...
     }
}

Units of code that are listed using the @uses annotation are allowed to be executed during the test but no code coverage information will be collected for them.

Configuring Strict Coverage

To enable the strict coverage mode, either use --strict-coverage on the command-line or set checkForUnintentionallyCoveredCode="true" in your PHPUnit XML configuration file.

The strict coverage mode is also enabled when PHPUnit is used in strict mode. PHPUnit's strict mode can be enabled by using --strict on the command-line or by setting strict="true" in your PHPUnit XML configuration file.

Über den Autor

Sebastian Bergmann

Sebastian Bergmann is the author of PHPUnit and sets the industry standard of quality assurance.