PHPUnit 的代码覆盖率

Code Coverage with PHPUnit

提问人:Dave 提问时间:4/21/2011 最后编辑:halferDave 更新时间:3/5/2016 访问量:11088

问:

我在尝试确定我们网站上的代码覆盖率时遇到了问题。我让 PHPUnit 在三个应用程序上运行单元测试时生成一个 html 代码覆盖率报告。我们有一个公共应用程序、一个管理应用程序和一个报告应用程序。我想以某种方式将这些合并到一个代码覆盖率报告中,因为应用程序共享代码。

代码覆盖率似乎只是在计算测试“接触”的文件的覆盖率,因此在计算中没有使用完全未经测试的文件。有谁知道如何将这些未使用的文件拉入计算中?有没有办法告诉覆盖率生成器使用某些目录进行计算,以便它拉入未触及的文件?我在 phpunit 的配置文件中设置了一个白名单,设置为我们项目的根目录。欢迎所有评论、答案和建议。

php phpunit 代码覆盖率 phpundercontrol

评论

1赞 Ira Baxter 4/21/2011
显而易见的答案是编写调用未触及文件的测试。
0赞 Dave 4/21/2011
这是真的,但我试图避免这种情况,因为我想获得一个相对准确的代码覆盖率百分比,以便设定目标。在线的 PHPUnit 文档似乎给人的印象是将这些文件添加到白名单中将包含它们,但我不太确定。
0赞 Obaid Maroof 3/20/2014
我不知道我是否真的理解你的问题,但你为什么要在代码覆盖率报告中包含未触及的文件?例如,如果有一个脚本 A 在运行 testX 时无事可做(因此未被触及),为什么脚本 A 应该包含在代码覆盖率报告中???

答:

-1赞 Ira Baxter 4/21/2011 #1

我认为 PHPUnit 使用 XDebug,它为实际执行的文件提供了字面上的覆盖率数据。它无法为从未执行的文件提供数据,因为调试器永远不会看到它们。您可以手动修补 PHPUnit 机制,将您认为在应用程序中的所有文件的列表添加到从 XDebug 返回的结果中。

我们的 PHP 测试覆盖率工具的工作方式不同。你给它一个你认为的所有文件的列表 是您申请的一部分;它可以帮助您构建此列表。(这与您必须修补到第一个解决方案中的列表相同)它检测所有提到的文件,并收集测试覆盖率数据。您现在获得的覆盖率数据正确地包含了所有内容。它应该可以与 PHPUnit 一起使用。

你可以走得更远。您可以为每个“独立”应用程序创建测试覆盖率,并单独运行它们。然后,您可以合并所有数据集的覆盖率数据,以查看整个集合的覆盖率。

评论

3赞 cweiske 4/30/2011
PHPUnit 还支持列出未在其覆盖率报告中运行的代码,只需将其添加到您的 .停止传播 FUD。phpunit.xml
5赞 edorian 4/21/2011 #2

如果你在配置文件中设置了一个,你应该看到所有未覆盖的文件。这可能是路径的问题,请尝试绝对路径,看看它为某些文件创建了 0% 的覆盖率,然后使相对路径起作用。<whitelist>phpunit.xml

对于结合覆盖范围,我所知道的 phpunit 没有太多可以做到的。您可以手动组合覆盖率结果(PHPUnit_Coverage包),然后弄清楚如何渲染它们,但您需要手动完成。至少我不知道有任何项目/工具/方法可以为您做到这一点。

最简单的方法是在一次 phpunit 运行中运行所有 3 个测试套件,并让它为您要访问的部分生成代码覆盖率。

评论

0赞 Dave 4/22/2011
是的,问题是我有三个单独的应用程序运行它们。因此,它必须是三个单独的 phpunit 调用。感谢您提供白名单中的信息,我会仔细检查我的路径。
0赞 edorian 4/23/2011
为什么你不能在一个 php 进程中运行所有这三个应用程序?
0赞 Dave 4/26/2011
我们有一个 phpunit-admin 来运行管理应用程序,一个用于报告应用程序的 phpunit-reporting。
0赞 edorian 4/26/2011
您在phpunit调用周围有自定义包装器脚本,或者这些.xml文件还是什么?:)对不起,除了说“创建一个运行所有应用程序的 phpunit-all”之外,您并没有真正给我一些东西可以工作
0赞 Dave 4/29/2011
是的,包装脚本基本上只是为该应用程序定义一组常量。每个应用都需要以不同的方式设置常量。
-1赞 james 4/22/2011 #3

这听起来可能很疯狂,但为什么不创建一个测试用例,以递归方式循环访问您的项目文件夹,并在它找到的每个文件上运行require_once呢?这应该允许 XDebug 为每个所需的文件创建一个新的代码覆盖率 html 文件。

评论

0赞 Dave 4/23/2011
蛮 力!这真的行得通吗?如果是这样,这可能是一个快速解决方案,直到我能弄清楚一些不那么“黑客”的东西。谢谢詹姆斯!
0赞 Dave 4/23/2011
另外,我们正在使用symfony框架,目前正在测试的一些操作有重复的名称。(例如 listAction)我们有一个类名管理器,我们在我们的网站上使用它来避免与此相关的一些问题。如果文件名相同,运行 require_once 不会导致错误吗?
0赞 Edson Medina 10/11/2012
不同目录中的相同文件名不是问题。
0赞 Edson Medina 10/11/2012
这种方法的问题在于,某些文件可能包含您可能不想执行的可执行代码(即:方法/函数之外)
0赞 james 12/18/2012
嘿,伙计们,我说这太疯狂了!
0赞 ts. 4/22/2011 #4

我遇到了同样的问题,我只是在运行测试套件之前添加了测试存根的生成(针对每个类和公共方法)。在phpUnit中,你甚至可以选择:

http://www.phpunit.de/manual/current/en/skeleton-generator.html

评论

0赞 Dave 4/23/2011
不知道 PHPUnit 能够生成骨架代码!谢谢你!看起来我仍然会遇到我们的应用程序共享代码并生成单独的代码覆盖率报告的问题。
0赞 ts. 4/23/2011
@Dave Dohr :您应该在一个脚本中运行三个套件,并使用 PHP_CodeCoverage::merge() 连接来自这些实例的数据,然后生成 HTML/Clover 报告
0赞 Dave 4/26/2011
我正在使用巡航控制在蚂蚁脚本中运行套件。我该怎么做?谷歌搜索PHP_CodeCoverage::merge()无济于事。
2赞 Jens A. Koch 11/10/2012 #5

像这样使用:<whitelist processUncoveredFilesFromWhitelist="true">

<filter>
  <whitelist processUncoveredFilesFromWhitelist="true">
    <directory suffix=".php">../folder/</directory>
  </whitelist>
</filter>