<< previous article: PHPUnit 4.0: Test Proxies next article: ConFoo >>

PHPUnit 4.0: Code Coverage Improvements

Sebastian Bergmann | 03/10/2014 | Blog

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:

              <?php
class BankAccount
{
    public function deposit(Money $money)
    {
        // ...
    }
}
            

              <?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:

              <?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.


Do you need help with test automation? Sebastian Bergmann, creator and project lead of PHPUnit, offers on-site trainings and workshops. He has over a decade of experience helping companies and Open Source projects around the world to leverage PHPUnit for unit tests, integration tests, and system tests.


<< previous article: PHPUnit 4.0: Test Proxies next article: ConFoo >>