如果设置 processUncoveredFilesFromWhitelist="true",如何从 PHP 单元中的代码覆盖处理中排除方法

How to exclude a method from code coverage processing in PHP unit if you set processUncoveredFilesFromWhitelist="true"

我在我的 phpunit.xml 中设置了以下功能:

<filter>
    <whitelist  addUncoveredFilesFromWhitelist="true" processUncoveredFilesFromWhitelist="true">
       <directory suffix=".php">/my/app</directory>
    </whielist>
</filter> 

我运行 测试:

 phpunit -c /path/to/phpunit.xml --coverage-text

但是,我不希望对一个文件中的一种方法进行覆盖率评估,因为它会向我的文本测试覆盖率报告输出一堆垃圾。假设 class/method 被命名为 my\app\Response::render()

此方法的简化版本是:

public function render($response) {
     header($response['status']);
     echo $response['body'];
     echo "\n";
}

render() 方法发出一个 header() 命令以及多个 echo() 命令,这些命令会导致在 运行ning 覆盖率报告时抛出大量文本和错误--coverage-text.

我尝试了以下操作:

也不阻止方法的执行(以某种方式)。

我考虑过一种 hack,例如将一些代码添加到此方法中,检查我们是否通过 phpunit 执行,例如将代码包装在:

 if(strpos($GLOBALS['argv'][0], 'phpunit') !==false){
     // ... do stuff
 }

或者,就像使用一个很好的旧 $do_debug 变量方法一样,通过 phpunit 传递一个环境变量,在 phpunit.xml 中指定以禁用此代码(这种方式如果以后我想要 运行 phpunit 并执行方法,只需切换环境变量即可)。

None 这些选项看起来很优雅。我不喜欢修改我的代码来解决测试问题(我什至有点不高兴向我的方法添加测试提示注释,我宁愿用某种 white/black 列表来处理它)。

然而,当一些需要不太优雅的解决方案的感知限制出现在一组经过良好审查的库中时,我喜欢对照社区检查我的头脑,看看是否有什么被忽视了。

任何人都知道我如何才能防止仅在 Phpunit 的功能中处理此方法?

显然,未被测试显式调用的方法不会被执行——有或没有 processUncoveredFilesFromWhitelist="true"。只有从测试中调用的全局和静态函数;在测试中调用的实例化 class 的方法;或任何类似于从测试操作级联的依赖项堆栈中的前两项的任何内容得到 运行 (据我所知)。

除非您使用某种形式的模拟,test-double,等等...来替换或避开有问题的方法,没有任何东西可以阻止在 运行ning 时调用的方法的执行您的单元测试和检查覆盖率。

这完全有道理。

事实证明,在我的例子中,在 /my/app 目录某处找到的文件之一是普通的 PHP 文件(不是 class 文件)。

当您指定 processUncoveredFilesFromWhitelist="true" 时,如果该文件具有任何全局可执行文件 php,它将获得 运行。它实例化的任何 classes 或它调用的 methods/functions 就像任何其他代码执行一样。

我正在使用遵循通用 PHP 范例的自定义 MVC Web 框架。里面

  /my/app/public

有一个简单的 index.php 可以实例化一个新的应用程序并执行它。 类似于:

<?php

$app = new app\MyApp();
$app->handleRequest();

通过打开 processUncoveredFilesFromWhitelist="true" index.php 的反应方式与它被从 nginxphp-fpm 配置为使用文件——它启动了应用程序。

我将文件 /my/app/public/index.php 添加到我的白名单块中:

<filter>
    <whitelist  addUncoveredFilesFromWhitelist="true" processUncoveredFilesFromWhitelist="true">
        <directory suffix=".php">/my/app</directory>
        <exclude>
            <file>/my/app/public/index.php</file>
        </exclude>
    </whitelist>
</filter>