我测试的代码充满了最终的静态类。 虽然我们无法重构它以获得更好的测试,但我有一个中间解决方案,可以在它自己的进程上运行几个小测试。 一切正常。 但是我没有得到覆盖率报告,因为一个覆盖了另一个。
我目前正在三叶草中生成报告,但我对其他报告非常开放。
我的测试仅在 phpunit 运行时有效:
/home/y/bin/phpunit --coverage-html clover --coverage-clover clover/report.xml --include-path src/ tests/aTest.php
OK (1 test, 1 assertions)
/home/y/bin/phpunit --coverage-html clover --coverage-clover clover/report.xml --include-path src/ tests/bTest.php
OK (1 test, 1 assertions)
/home/y/bin/phpunit --coverage-html clover --coverage-clover clover/report.xml --include-path src/ tests/cTest.php
OK (1 test, 1 assertions)
但这会导致每次运行都擦除前一次报告。所以我只得到最后一个的报告。如果我尝试按照 phpunit 期望生成完整报告的方式运行它们,我就会失败,因为我的所有类都包含自己的静态类。
/home/y/bin/phpunit --coverage-html clover --coverage-clover clover/report.xml --include-path src/ tests/
. (first test pass)
PHP Fatal error: Cannot redeclare class Something
make[1]: *** [phpunit_run] Error 255
(但即使使用--process-isolation --no-globals-backup
上述内容也会失败,因为这不是它们的意思...... -- 这不是关于如何在 php 单元上正确获得进程隔离的另一个问题。 我可以运行几次,我只想:)获得完整的覆盖报告
有没有办法让测试像第一个代码块一样正确运行(即在多个进程上以避免污染的全局类声明空间),但仍然具有全面的代码覆盖率报告?
谢谢!
Schleis 的回答对我不起作用。在我的情况下,unserialize() 方法抛出了一个错误:偏移错误...
但是,有一种非常简单的方法可以实现此目的:
按照此处所述下载 phpcov 。
让 phpunit 生成 php 覆盖率报告:
phpunit --coverage-php coverage/cov/foo.cov tests/foo
phpunit --coverage-php coverage/cov/bar.cov tests/bar
现在你有 2 个 .cov 文件。然后在你最喜欢的外壳中:
phpcov merge --clover clover.xml /coverage/cov
它将生成一个三叶草.xml报告文件。
您必须编写解决方案的脚本,我不知道让 phpunit 将其他运行的覆盖范围加在一起的选项。 但是phpunit代码使这不会太痛苦。
您需要使用--coverage-php
选项来获取覆盖范围报告。 这将使使用 php 脚本将它们组合在一起变得更加容易。 此选项输出包含序列化PHP_CodeCoverage对象的文件。 此对象具有可用于合并报表的方法merge
。 然后,可以使用相应类型的报表对象为您生成输出。
https://github.com/sebastianbergmann/php-code-coverage/tree/master/src/CodeCoverage/Report
由于现在用于分发 PHPUnit 的 .phar 文件,我在包含 PHPUnit 对象时确实遇到了问题。 您可能需要考虑将此 .gist 用于您自己的自动包含。
您的脚本将如下所示:
$fileList = ['file1', 'file2', 'file3']; //or read from dir, however you get the list.
$coverageReports = [];
foreach($fileList as $file) {
$coverageReports[] = unserialize(file_get_contents($file));
}
$mainReport = new PHP_CodeCoverage(); //Could also use one of the other ones that were generated.
foreach($coverageReports as $coverageReport) {
$mainReport->merge($coverageReport);
}
//Change this object depending on the format you want.
$htmlReport = new PHP_CodeCoverage_Report_HTML();
$htmlReport->process($mainReport);