使用#3272 和#3290,在使用 Xdebug 2.6(或更高版本)时,代码覆盖率数据的收集和处理性能显着提高。
现在,这需要使用--dump-xdebug-filter
调用 PHPUnit,以便在phpunit.xml
中更改白名单配置时为 Xdebug 生成带有白名单配置代码的 PHP 脚本。 然后需要使用--prepend
调用 PHPUnit 以在加载任何其他代码之前加载生成的 PHP 脚本。
这张票提出了删除--dump-xdebug-filter
和--prepend
选项的想法(现在这不会是 BC 中断,因为此时它们从未被释放),而是总是生成一个.phpunit.xdebug.filter
调用 PHPUnit 的目录中的 PHP 脚本(类似于.phpunit.result.cache
)并自动加载此文件(如果它存在并且使用 Xdebug > 2.6)。
@sebastianheuer @hollodotme你认为这有意义/可行吗?
@sebastianbergmann对我来说绝对有意义,实际上我更喜欢这种建议的方法,因为当前的实现需要更新每个 CI 配置以调用 phpunit 两次(每个测试套件)。
+1,但这是否仍然需要两次运行phpunit?
第一次运行会很慢,后续运行会很快(呃)
我们可能需要将phpunit.xml
的哈希值存储在.phpunit.xdebug.filter
中,并且在它过期时不加载它。
密切关注配置并确定缓存对于新配置是否仍然相关(甚至有效)也是我遇到的问题。
处理缓存测试重新排序时弹出的内容:
我有一些改进缓存的草图,在这种边缘情况下表现得更好。
我看到的一个问题(在实现这个时)是由在加载任何 PHPUnit 代码之前调用xdebug_set_filter()
的要求引起的 - 我如何在 PHPUnit 被引导之前获取配置的哈希并且我知道哪个实际使用了配置文件(如果有的话)?
@sebastianheuer好点。 所以我的问题是,如果.phpunit.xdebug.filter
每次都根据phpunit.xml
的白名单被转储,然后 phpunit 使用--prepend .phpunit.xdebug.filter
调用自身,那么我的问题是整体执行速度减慢了多少选项。 恕我直言,阅读配置、转储白名单过滤器和重新启动 PHPUnit 不应该对整体执行时间产生太大影响。
转储白名单非常快,它可能会增加总执行时间 2 秒。 我记得@sebastianbergmann和我在代码冲刺期间讨论过这种行为,但感觉有点奇怪。
@hollodotme我不想要的一件事是重新启动 PHPUnit。 这将增加的复杂性不会,IMO,也不能通过让第一次运行更快(er)来证明是合理的。
是的,程序自行重启有点奇怪。 据我所知,尽管作曲家在某些情况下会这样做。 让用户明白这一点的想法怎么样。 而不是phpunit --dump-xdebug-filter
+ phpunit --prepend .phpunit.xdebug.filter
只需运行phpunit --xdebug-filter
组合两个命令。 所以用户可以选择。 这也将允许关闭整个功能并快速比较使用 Xdebug 过滤器的执行和不使用 Xdebug 过滤器的执行之间的结果。
编辑: @sebastianbergmann抱歉,发帖时没有看到您的评论。
@sebastianbergmann您将如何处理有关您最初提案的第二次调用? 还是您的意思是第一次运行转储文件,但不应用 Xdebug 过滤器并且因此速度较慢?
我不想要的一件事是重新启动 PHPUnit。 这将增加复杂性(...)
@sebastianbergmann , https://github.com/composer/xdebug-handler可能是一个有趣的想法 - 在这种情况下并不完美,但它可以自动重启 CLI 命令的时间和方式
@hollodotme这正是我的意思。
@keradus我知道xdebug-handler,但即使只是使用它(无需自己实现功能)也会增加太多复杂性,IMO。
另一种方法可能是在引导 PHPUnit 之前首先将 PHPUnit 自己的代码列入黑名单,并在加载测试之前为被测代码设置白名单。 一个快速的概念验证证明带来了与前置白名单几乎相同的速度改进。
我确实认为这种方法可能最适合 PHAR,因为它包含所有依赖项,而当通过 composer 安装时,只有部分 PHPUnit 会被列入黑名单,因为项目的供应商目录不会成为黑名单的一部分。
虽然这不会给我们带来最大的好处,但它不需要在用户端进行任何更改或额外的步骤。
我喜欢这种方法@sebastianheuer!
黑名单和白名单可以一起使用吗?
根据 Xdebug 的文档不是,但它似乎又可以工作了 ;) 在不了解内部情况的情况下,我只能假设白名单替换了黑名单,在这种情况下这是可以的,因为在那个时间点已经加载了所有后备列表的代码这样就不会收集到覆盖信息。
@sebastianheuer我认为它实际上并没有在您的实现中结合使用。 我认为第二个xdebug_set_filter
删除了黑名单并设置了白名单,这也排除了您在黑名单中的路径,我假设。 IMO,为了测试这一点,我们需要检查黑名单和白名单中的路径会发生什么。
我想从@derickr那里得到关于这个的意见。 然而,他目前正在度假 AFAIK。
我认为最好像 Composer 那样自动重启 PHPUnit,这样所有用户都会受益,即使是那些根本没有听说过缓存的用户。
@sebastianheuer你能实现这个并发送一个拉取请求吗?
作为 PHPUnit 7.4 的一部分,我将在下周发布我们现在拥有的东西( @sebastianheuer在上一次代码冲刺期间实现的东西)。 我们可以稍后改进。
我在实现作曲家风格的重启方面有点挣扎。 我现在能想象的最简单的事情之一就是使用来自$argv
的命令调用passthrough()
#$ 。 我在 PoC 中进行了这项工作,但它需要一些较小的更改,例如在第二次运行中省略版本输出 - 我无法真正想象那里可能存在的陷阱。 这是你的想法吗, @sebastianbergmann ?
添加我的两分钱:谈到--dump-xdebug-filter
,如果生成的 PHP 脚本在xdebug_set_filter
函数不存在时警告我们,那就太好了。
目前,它只是默默地不做任何事情,我们显然不会检查这部分。
@Soullivaneuh恐怕我们对此无能为力(这是有道理的)。
如果您的 Xdebug 没有xdebug_set_filter()
,那么您不仅会错过这个功能,还会错过很多错误修复。 只是说:-)
@sebastianbergmann也许是一个早期的叉子,它在稍后包含的预定义位置(叉子之前)生成文件?
这可能是一个干净的解决方案,其中 fork 只是执行转储。
更进一步的可能是使用共享内存 + eval 以便磁盘没有写入任何内容?
这与通过phpdbg
运行phpunit
是否有任何比较,我已经看到它提供了一些性能改进。
例如:
phpdbg -qrr vendor/bin/phpunit
(选项q
uiet rr
un 并退出)
phpdbg
可能更快,但根据我的经验,它提供的数据不如 Xdebug 提供的数据准确。 这就是为什么我现在不关心phpdbg
的原因。
这很有趣,谢谢,你有关于这些准确性问题的更多信息吗?
提示:
DE: Habe gerade den Artikel erst gefunden (https://thephp.cc/news/2019/01/faster-code-coverage) 但是...
如果您不使用作曲家自动加载(opcache 和其他缓存关闭),则改进很低,但会改进:-)
Runtime: PHP 7.3.9-1+0~20190902.44+debian10~1.gbpf8534c with Xdebug 2.7.2
Phpunit via composer, not as phar.
Tests: 732, Assertions: 2539, Errors: 1, Skipped: 2.
--> before >--
Generating code coverage report in HTML format ... done [2.38 seconds]
./runCoverageCreate.sh src/ 29,17s user 1,21s system 82% cpu 36,999 total
--> after >--
Generating code coverage report in HTML format ... done [1.99 seconds]
./runCoverageCreate.sh src/ --prepend build/xdebug-filter.php 28,45s user 1,01s system 81% cpu 36,341 total
好。 这似乎是 vendor/phpunit/* 的东西
我希望默认情况下(或已经在?)不实施/激活这种改进。 phpunit.xml 的标志会很好!
我认为最坏的情况是默认情况。
对于 phpunit.xml 配置生成器作为请求启用它的选项(默认为“Y”)
亲切的问候
我认为进一步追求这一点没有任何价值。 就个人而言,我不久前停止使用 Xdebug 进行代码覆盖,而是使用 PCOV。 最终,我们甚至可能想要删除--dump-xdebug-filter
,因为--prepend
的实现是一种 hack(因为它必须如此)。
最有用的评论
作为 PHPUnit 7.4 的一部分,我将在下周发布我们现在拥有的东西( @sebastianheuer在上一次代码冲刺期间实现的东西)。 我们可以稍后改进。