PHP XDEBUG 扩展 | 文档

代码分析能够告诉你在一个请求中脚本中的哪一行(或者脚本的设置)被执行了。比如利用这个信息你可以发现你的单元测试的好坏程度。


Xdebug 的代码覆盖功能经常和 PHP_CodeCoverage 结合使用,用做 PHPUnit 运行的一部分。PHPUnit 将代码覆盖率收集委托给 Xdebug。它通过 xdebug_start_code_coverage()xdebug_stop_code_coverage() 为每个测试开启和停止代码覆盖,使用 xdebug_get_code_coverage() 来取出结果。

代码覆盖的主要输出是一个数组,详细说明在运行代码覆盖集合活跃的代码时,哪些文件哪些行被“击中”。 但代码覆盖功能还可以在产生额外性能影响的情况下,分析哪些代码行上有可执行代码,哪些代码行实际可以被命中(无用代码分析),还可以进行检测以找出函数和方法中的哪些分支和路径被追踪。xdebug_start_code_coverage() 函数记录了各种选项。

过滤

Xdebug 2.6 引入了代码覆盖的过滤功能。使用过滤器在代码覆盖率收集期间你可以通过白名单包括,或通过黑名单排除,被分析的路径或类名前缀。一个典型的用例是将过滤器配置为只包含 src/ 文件夹,以便 Xdebug 的代码覆盖率分析不会尝试分析测试,Composer 依赖项或 PHPUnit / PHP_CodeCoverage 本身。 如果正确配置过滤器,则可以预期代码覆盖率运行速度提高2倍 [1, 2, 3].

过滤器的工作原理是根据配置的过滤器标记每个可执行单元(函数,方法,文件)。 Xdebug 只在特定可执行单元第一次被 include/require 时才这样做,因为 PHP 第一次解析和编译一个文件时才会发生过滤。 Xdebug 需要在这时这样做,也是因为当这时它会分析哪些路径能运行,可执行单元的哪些行不能执行。在这时标记可执行单元,也意味着比如 Xdebug 想要计算包含在代码覆盖中的行时不必每一次运行过滤器。 因此,在代码被 include/require 之前设置过滤器非常重要。目前最好使用 PHP 的 auto_prepend_file 设置通过自动前置文件来完成。

设置过滤器只展示 src/ 文件夹的代码覆盖率分析,你可以这样调用 xdebug_set_filter()

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

设置这个过滤器后,代码覆盖率信息将只包含位于 src/ 文件子目录的函数,方法和文件。你可以告诉 PHP 添加前置文件通过调用:

php -dauto_prepend_file=xdebug_filter.php yourscript.php

或者结合 PHPUnit,当通过 Composer 安装时,使用:

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

xdebug_set_filter() 参数介绍的完整文档在其自己的文档页面。


相关设置


xdebug.coverage_enable
类型:布尔值,默认值: 1, 由 Xdebug >= 2.2 引入
如果这个设置设置为 0,那么 Xdebug 将不会设置内部结构来允许代码覆盖。这能让 Xdebug 速度加快一点,但是代码覆盖率分析将不会工作。

相关函数


boolean xdebug_code_coverage_started()
返回代码覆盖是否活跃

返回代码覆盖是否已经开启。

示例:

<?php
    var_dump
(xdebug_code_coverage_started());

    
xdebug_start_code_coverage();

    
var_dump(xdebug_code_coverage_started());
?>  

返回:

bool(false)
bool(true)


array xdebug_get_code_coverage()
返回代码覆盖信息

返回一个数组结构,包含哪些行在脚本中(包括 inlcude 的文件)被执行了的信息。下面的示例展示了一个指定文件的代码覆盖:

示例:

<?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());
?>  

返回:

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 )
设置过滤器
由 2.6 版本引入

当展示堆栈跟踪或者记录函数跟踪时,或者当收集代码覆盖时,这个函数配置 Xdebug 使用的过滤器。过滤器配置应用于每个独立的执行单元(函数,方法,脚本主体)。

第一个参数, $group 选择要设置过滤器的功能。目前有两组

XDEBUG_FILTER_TRACING
用于在错误之上过滤堆栈跟踪以及函数跟踪的过滤器组。
XDEBUG_FILTER_CODE_COVERAGE
用于限制 Xdebug 代码覆盖分析的文件路径的过滤器组。
每个组都可以单独配置。

你可以设置不同类型的过滤器。对于文件路径或完全限定类名,有一个白名单和黑名单选项。 XDEBUG_FILTER_CODE_COVERAGE 组仅支持 XDEBUG_PATH_WHITELISTXDEBUG_PATH_BLACKLIST,和 XDEBUG_FILTER_NONE。所有的匹配都不区分大小写。

用做第二个参数 "$list_type" 的常量是:

XDEBUG_PATH_WHITELIST

设置文件路径的白名单。如果执行单元的文件路径以作为第三个参数 $configuration 的数组中的任何前缀作为前缀,则输出中包含执行单元。

请注意,前缀 "/home/derick" 也会匹配 "/home/derickrethans" 中的文件,因此建议在前缀中添加尾部斜杠以防止这种情况发生。

XDEBUG_PATH_BLACKLIST
设置文件路径的黑名单。如果执行单元的文件路径以 $configuration 数组中的任何前缀作为前缀,则它将从输出中排除。
XDEBUG_NAMESPACE_WHITELIST

为类前缀设置白名单。如果命名空间扩展后的类名,匹配 $configuration 数组中的前缀中的其中一个,则输出中包含执行单元。 "" 是特殊的,表示不属于类的函数。这些是用户定义或内置的 PHP 函数(例如 strlen())。

命名空间扩展在 PHP 中自动识别,它的引擎会始终看见完全限定类名。在下面的代码中,完全限定类名 DramIO\Whisky

Example:

<?php
namespace DramIO;

class 
Whisky {
}

为了匹配命名空间中所有类,建议使用命名空间分隔符指定前缀。

XDEBUG_NAMESPACE_BLACKLIST
与白名单相反。仅当前缀匹配了 $configuration 数组中前缀的其中一个,则执行的单元被排除。
XDEBUG_FILTER_NONE
关闭所选 $group 的过滤器。

不能同时配置黑名单和白名单,或者为路径和命名空间配置黑名单/白名单。 在任意的一个时间,四种列出的类型中只有一种能活跃。但是可以使用 XDEBUG_FILTER_NONE 完全关闭过滤器。

排除跟踪 vendor 子目录中所有文件:

示例:

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

包含跟踪中的函数调用(不在类名之下),ezcDramIO\ 类下的方法调用:

示例:

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

只在 src 子目录下执行代码覆盖分析:

示例:

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

void xdebug_start_code_coverage( [int options] )
开启代码覆盖

这个函数开始统计代码覆盖的信息。这个信息由二维数组组成,数组主下标是执行的文件名字,第二个索引是行号。返回的值代表代码行是否已经执行或者是不可执行的代码行。

每一行返回的值:

  • 1: 该行已经执行
  • -1: 该行没有执行
  • -2: 该行没有可执行代码
-1 只有在 XDEBUG_CC_UNUSED 开启时会返回,值 -2 只有在 XDEBUG_CC_UNUSEDXDEBUG_CC_DEAD_CODE 都开启时才会返回。

这个函数有三个选项,他们是位字段:

XDEBUG_CC_UNUSED
开启代码扫描来找出哪一行被执行过了。没有这个选项返回的数组中只有已经被执行过的代码行。
XDEBUG_CC_DEAD_CODE
开启分支分析来计算代码是否被执行过了。
XDEBUG_CC_BRANCH_CHECK
开启执行路径分析。
开启这些选项会让代码覆盖的速度大幅度的降低。

可以像下面示例中展示的一样使用这个选项。

示例:

<?php
xdebug_start_code_coverage
XDEBUG_CC_UNUSED XDEBUG_CC_DEAD_CODE );
?>

void xdebug_stop_code_coverage( [int cleanup=1] )
停止代码覆盖

这个函数会停止收集信息,内存中的信息将会被销毁。如果传递 0 作为参数,那么代码覆盖将不会被销毁,以至于可以再次使用 xdebug_start_code_coverage() 函数来继续收集信息。


 
 
版权所有 © 2002-2019 Derick Rethans
由 Monica 基于 https://xdebug.org/ 翻译,最后修改:2019-08-01
E-mail: MonicaPu2014@Gmail.com
京 ICP 备 16054607 号