PHPUnit使用Pcov驱动时function_exists判定行覆盖率缺失问题求解
问题原因
这个现象是Pcov的覆盖率收集机制和加载时机不匹配导致的:
- 这两个助手函数所在的文件,一般是通过Composer自动加载机制在测试流程启动前就完成加载的,此时Pcov还未启动覆盖率收集,因此这两行
if (!function_exists())的执行过程没有被统计到 - if块内的函数是在测试用例执行阶段被调用的,此时Pcov已经进入收集状态,所以函数内部的代码可以被正常标记为已覆盖
- Xdebug没有这个问题是因为Xdebug的覆盖率收集是随扩展启用全局生效的,自动加载阶段的代码执行也会被纳入统计
解决方法
你可以根据自己的项目情况任选以下方案:
- 调整Pcov启动时机
在测试启动文件(一般是tests/bootstrap.php)的最开头,引入Composer自动加载文件之前添加pcov_start()代码,确保自动加载执行前Pcov就已经启动收集:
运行测试时无需额外加参数,即可正常统计到自动加载阶段执行的顶级作用域代码。<?php pcov_start(); // 放在第一行,早于autoload引入 require __DIR__ . '/../vendor/autoload.php'; - 升级Pcov版本
1.0.x系列的早期Pcov版本存在顶级作用域条件分支统计遗漏的已知bug,升级到最新稳定版即可解决该问题。 - 配置忽略非业务代码(可选)
如果你不需要统计这类函数存在性判断的代码,可以在两行if判断前添加PHPUnit覆盖率忽略注释,避免拉低整体覆盖率:// @codeCoverageIgnoreStart if (!function_exists('birthday_to_age')) { // @codeCoverageIgnoreEnd
内容的提问来源于stack exchange,提问作者Tony Tao
相关产品推荐
相关产品推荐

