Quantcast
Channel: Symfony Blog
Viewing all articles
Browse latest Browse all 3057

New in Symfony 3.4: Better code coverage reports

$
0
0
Grégoire Pineau

Contributed by
Grégoire Pineau
in #23149.

Code coverage is a measure describing the degree to which the source code of a program is tested by a particular test suite. Code with high code coverage has been more thoroughly tested and has a lower chance of containing bugs. PHPUnit provides utilities to measure code coverage, but they are not precise enough.

Consider this simple example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
classBar{publicfunctionbarMethod(){return'bar';}}classFoo{private$bar;publicfunction__construct(Bar$bar){$this->bar=$bar;}publicfunctionfooMethod(){$this->bar->barMethod();return'bar';}}

If your test looks as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
classFooTestextendsPHPUnit\Framework\TestCase{publicfunctiontest(){$bar=newBar();$foo=newFoo($bar);$this->assertSame('bar',$foo->fooMethod());}}

PHPUnit considers a line code as tested as soon as it's been executed. TheFooTest::test method executes every line of code of the Foo and Bar classes, so the code coverage calculated by PHPUnit will be 100%. However, this is not precise because the Bar class is not really tested.

The solution is to use the PHPUnit @covers annotation on each test class to specify which class a test is testing. This solution is cumbersome and hard to maintain, so in Symfony 3.4 we've added a CoverageListener to thePHPUnit Bridge component to provide better code coverage reports.

The only change you need to make in your application is to register CoverageListener as a PHPUnit listener in the phpunit.xml config file:

1
2
3
4
5
6
7
8
9
<phpunitxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.0/phpunit.xsd"><!-- ... --><listeners><listenerclass="Symfony\Bridge\PhpUnit\CoverageListener"/></listeners></phpunit>

This listener checks every test class and does the following:

  1. If the class has a @covers annotation, do nothing;
  2. If no @covers annotation is found, find the code tested by this class automatically and add the annotation.

The logic used to find the tested code is based on Symfony's best practices: tests use the same directory structure as code and add a Test suffix to the class names. For example, if the test class is My\Namespace\Tests\FooTest, the related class is guessed as My\Namespace\Foo.

If this guessing logic is too simple or doesn't work for your application, you can provide your own solver to the PHPUnit listener:

1
2
3
4
5
6
7
<listeners><listenerclass="Symfony\Bridge\PhpUnit\CoverageListener"><arguments><string>App\Test\CoverageSolver::solve</string></arguments></listener></listeners>

Be trained by Symfony experts - 2017-10-9 Lyon - 2017-10-9 Lyon - 2017-10-9 Paris

Viewing all articles
Browse latest Browse all 3057

Trending Articles