覆盖率报告为空或全0%大概率因xdebug未在cli启用:需执行php -m确认加载,php -i检查xdebug.mode=debug,coverage(无空格),且phpunit.xml路径配置正确、phpunit版本≥9.3兼容xdebug 3与php 8+。

覆盖率报告为空或全是 0%,大概率不是 PHPUnit 配置错了,而是 Xdebug 根本没在 CLI 下生效。
确认 Xdebug coverage 模式确实在 CLI 中启用
很多人改了 php.ini 却忘了 PHP CLI 和 Web SAPI(如 Apache/Nginx)用的是不同配置文件。运行测试时用的是 CLI,所以必须检查 CLI 环境:
- 执行
php -m | grep xdebug—— 如果无输出,说明 CLI 没加载 Xdebug - 执行
php -i | grep "xdebug.mode"—— 输出应含coverage,不能是debug或空;Xdebug 3 要求显式写成xdebug.mode=debug,coverage(逗号间**不能有空格**) - 别依赖
phpinfo()页面判断:它反映的是 Web 环境,和phpunit命令无关
phpunit.xml 中的 <coverage></coverage> 配置必须匹配源码路径
路径写错会导致“目标代码没被纳入统计范围”,结果就是报告里压根不显示 src/ 下的文件,或者把 tests/ 也当被测代码算进去:
-
<include></include>定义的是“哪些源码要参与覆盖率计算”,通常只写<directory suffix=".php">src/</directory> -
<exclude></exclude>必须显式排除测试辅助类,例如<directory suffix=".php">src/Tests/</directory>,否则它们会拉低整体覆盖率 - 所有路径都是相对于
phpunit.xml所在目录的,不是项目根,也不是src/目录下 - 加上
processUncoveredFiles="true",否则未被任何测试执行的文件直接从报告中消失,你根本看不到“漏测”在哪
PHPUnit 版本与 Xdebug 兼容性不能忽略
PHP 8.1+ 项目若还在用 PHPUnit 9.2 或更老版本,--coverage-html 可能静默失败或生成空报告:
- PHPUnit ≥ 9.3 是 Xdebug 3 + PHP 8+ 的最低兼容门槛;推荐直接上 10.x
- 用
phpunit --version确认实际运行的是哪个版本 —— Composer 的 vendor bin、全局安装、Phar 包可能混用,导致行为不一致 - 别在
php.ini里设xdebug.start_with_request=yes:它会让所有 CLI 脚本变慢,只需跑覆盖率时临时启用
assertContains() 类断言不影响行覆盖,但影响分支覆盖
你看到某行 if 或 foreach 在 HTML 报告里是黄色(部分覆盖),不是因为没执行到,而是分支没走全:
-
$this->assertContains('a', $arr)这行本身算“已执行”,但若$arr永远不为空,那else分支就永远没触发 - 行覆盖率(line)和分支覆盖率(branch)是两套统计逻辑,默认
phpunit --coverage-html只显示 line;要查分支,得加--coverage-clover配合工具分析,或看 HTML 报告里每行右侧的小图标 - 函数/类覆盖率容易虚高——哪怕只调了一次
MyService::doSomething(),整个函数就算“已覆盖”,但内部逻辑可能大片空白
最常被跳过的环节是验证 CLI 下 Xdebug 是否真在 coverage 模式运行;其余问题基本都围绕路径配置和版本对齐。一旦报告里出现文件但行数全灰,说明插桩成功了,接下来才是测试用例本身的设计问题。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











