XDEBUG EXTENSION FOR PHP | DOCUMENTATION

Code coverage tells you which lines of script (or set of scripts) have been executed during a request. With this information you can for example find out how good your unit tests are.


Xdebug's code coverage functionality is often used in combination with PHP_CodeCoverage as part of PHPUnit runs. PHPUnit delegates the code coverage collection to Xdebug. It starts and stops code coverage through xdebug_start_code_coverage() and xdebug_stop_code_coverage() for every test, and uses xdebug_get_code_coverage() to retrieve the results.

Code coverage's main output is an array detailing which lines in which files have been "hit" while running the code with code coverage collection active. But the code coverage functionality can also, with an additional performance impact, analyse which lines of code have executable code on it, which lines of code can actually be hit (dead code analysis), and also can it do instrumentation to find out which branches and paths in functions and methods have been followed. The various options are documented with the xdebug_start_code_coverage() function.

Filtering

Xdebug 2.6 introduces filtering capabilities for code coverage. With a filter you can include through a white list, or exclude through a black list, paths or class name prefixes from being analysed during code coverage collection. A typyical use case would be to configure the filter to only include your src/ folder, so that Xdebug's code coverage analysis does not try to analyse tests, Composer dependencies, or PHPUnit/PHP_CodeCoverage itself. If you configure the filter correctly, you can expect a 2-fold speed increase for code coverage runs [1, 2, 3].

The filter works by tagging each executable unit (function, method, file) according to the configured filter. Xdebug can only do that the first time a specific executable unit is included/required, as the filtering happens when PHP parses and compiles a file for the first time. Xdebug needs to do it as this point, as this is also when it analyses which paths can run, and which lines of an executable unit can not be executed. Tagging executable units at this point, also means that the filter does not have to run every time Xdebug wants to count a line to be included in code coverage for example. It is therefore important to set-up the filter before the code is included/required. This currently can be best done through an auto-prepended file through PHP's auto_prepend_file setting.

To set-up a filter that only does code coverage analysis for the src/ folder, you would call xdebug_set_filter() with:

Example:
<?php
xdebug_set_filter(
	XDEBUG_FILTER_CODE_COVERAGE,
	XDEBUG_PATH_WHITELIST,
	[ __DIR__ . DIRECTORY_SEPARATOR . "src" . DIRECTORY_SEPARATOR ]
);
?>

With this filter set up, the code coverage information will only include functions, methods and files which are located in the src/ sub-directory of the file in which this file resides. You can tell PHP to add this prepend file by calling:

php -dauto_prepend_file=xdebug_filter.php yourscript.php

Or in combination with PHPUnit, when installed through Composer, with:

php -dauto_prepend_file=xdebug_filter.php vendor/bin/phpunit

The full documentation for the arguments to xdebug_set_filter() are described on its own documentation page.


Related Settings


xdebug.coverage_enable
Type: boolean, Default value: 1, Introduced in Xdebug >= 2.2
If this setting is set to 0, then Xdebug will not set-up internal structures to allow code coverage. This speeds up Xdebug quite a bit, but of course, Code Coverage Analysis won't work.

Related Functions


boolean xdebug_code_coverage_started()
Returns whether code coverage is active.

Returns whether code coverage has been started.

Example:

<?php
    var_dump
(xdebug_code_coverage_started());

    
xdebug_start_code_coverage();

    
var_dump(xdebug_code_coverage_started());
?>  

Returns:

bool(false)
bool(true)


array xdebug_get_code_coverage()
Returns code coverage information

Returns a structure which contains information about which lines were executed in your script (including include files). The following example shows code coverage for one specific file:

Example:

<?php
    xdebug_start_code_coverage
();

    function 
a($a) {
        echo 
$a 2.5;
    }

    function 
b($count) {
        for (
$i 0$i $count$i++) {
            
a($i 0.17);
        }
    }

    
b(6);
    
b(10);

    
var_dump(xdebug_get_code_coverage());
?>  

Returns:

array
  '/home/httpd/html/test/xdebug/docs/xdebug_get_code_coverage.php' => 
    array
      5 => int 1
      6 => int 1
      7 => int 1
      9 => int 1
      10 => int 1
      11 => int 1
      12 => int 1
      13 => int 1
      15 => int 1
      16 => int 1
      18 => int 1

void xdebug_set_filter( int $group, int $list_type, array $configuration )
Starts code coverage
Introduced in version 2.6

This function configures a filter that Xdebug employs when displaying stack traces or recording function traces, or when gathering code coverage. Filter configurations are applied to each execution unit (function, method, script body) independently.

The first argument, $group selects for which feature you want to set up a filter. Currently there are two groups:

XDEBUG_FILTER_TRACING
The filter group used for filtering Stack Traces upon errors, as well as Function Traces.
XDEBUG_FILTER_CODE_COVERAGE
The filter group used for restricting the file paths which Xdebug would use for Code Coverage Analysis.
Each group can be configured independently.

There are different kinds of filters that you can set. There is a white list and a black list option for either file paths or fully qualified class names. The XDEBUG_FILTER_CODE_COVERAGE group only supports XDEBUG_PATH_WHITELIST, XDEBUG_PATH_BLACKLIST, and XDEBUG_FILTER_NONE. All matches are done in a case-insensitive way.

The constants to use as second "$list_type" argument are:

XDEBUG_PATH_WHITELIST

Sets up a white list for file paths. An execution unit is included in the output if its file path is prefixed by any of the prefixes in the array passed as third $configuration argument.

Please note that a prefix of "/home/derick" would also match files in "/home/derickrethans", so it is recommended that you add the trailing slash to the prefix in order to prevent this.

XDEBUG_PATH_BLACKLIST
Sets up a black list for file paths. An execution unit will be excluded from the output if its file path is prefixed by any of the prefixes from the $configuration array.
XDEBUG_NAMESPACE_WHITELIST

Sets up a white list for class prefixes. An execution unit is included in the output if the class name, after namespace expansion, matches one of the prefixes in the $configuration array. The value "" is special, and means functions that do not belong to a class. These are either user-defined, or built-in PHP functions (e.g. strlen()).

Name space expansion happens automatically in PHP, and its engine will always see the full qualified class name. In the code below, the fully qualified class name DramIO\Whisky:

Example:

<?php
namespace DramIO;

class 
Whisky {
}

In order to match for all clases within a namespace, it is recommended to specify the prefix with the namespace separator

XDEBUG_NAMESPACE_BLACKLIST
The opposite of the white list. Execution units are excluded only if their prefix matches one of the prefixes in the $configuration array.
XDEBUG_FILTER_NONE
Turns off the filter for the selected $group.

It is not possible to configure both a black list and a white list, or a black-/white-list for paths and namespaces at the same time. Only one of the four list types can be active at any one time. It is possible however, to turn off the filter altogether by using XDEBUG_FILTER_NONE.

To exclude all files in the vendor sub-directory in traces:

Example:

<?php
xdebug_set_filter
XDEBUG_FILTER_TRACINGXDEBUG_PATH_BLACKLIST, [ __DIR__ "/vendor/" ] );
?>

To include only function calls (without class name), and methods calls for the ezc and DramIO\ classes in traces:

Example:

<?php
xdebug_set_filter
XDEBUG_FILTER_TRACINGXDEBUG_NAMESPACE_WHITELIST, [ """ezc""DramIO\" ] );
?>

To only perform code-coverage analysis for files in the src sub-directory:

Example:

<?php
xdebug_set_filter
XDEBUG_FILTER_CODE_COVERAGEXDEBUG_PATH_WHITELIST, [ __DIR__ "/src/" ] );
?>

void xdebug_start_code_coverage( [int options] )
Starts code coverage

This function starts gathering the information for code coverage. The information that is collected consists of an two dimensional array with as primary index the executed filename and as secondary key the line number. The value in the elements represents whether the line has been executed or whether it has unreachable lines.

The returned values for each line are:

  • 1: this line was executed
  • -1: this line was not executed
  • -2: this line did not have executable code on it
Value -1 is only returned when the XDEBUG_CC_UNUSED is enabled and value -2 is only returned when both XDEBUG_CC_UNUSED and XDEBUG_CC_DEAD_CODE are enabled.

This function has two options, which act as a bitfield:

XDEBUG_CC_UNUSED
Enables scanning of code to figure out which line has executable code. Without this option the returned array will only have lines in them that were actually executed.
XDEBUG_CC_DEAD_CODE
Enables branch analyzes to figure out whether code can be executed.
XDEBUG_CC_BRANCH_CHECK
Enables path execution analysis.
Enabling those options make code coverage drastically slower.

You can use the options as shown in the following example.

Example:

<?php
xdebug_start_code_coverage
XDEBUG_CC_UNUSED XDEBUG_CC_DEAD_CODE );
?>

void xdebug_stop_code_coverage( [int cleanup=true] )
Stops code coverage

This function stops collecting information, the information in memory will be destroyed. If you pass "false" as argument, then the code coverage information will not be destroyed so that you can resume the gathering of information with the xdebug_start_code_coverage() function again.


 
 
This site and all of its contents are Copyright © 2002-2018 by Derick Rethans.
All rights reserved.