我目前正在尝试获取基于Yii框架的PHP应用程序的代码覆盖率报告。
代码覆盖率由PHPUnit3.6生成,我使用白名单方法来过滤源文件。
问题是,当我设置选项addUncoveredFilesFromWhitelist="true"
时,代码覆盖率会中断,并出现以下错误:
Generating code coverage report, this may take a moment.PHP Warning: include(CButtonColumn.php): failed to open stream: No such file or directory in /home/hijarian/systems/yii/framework/YiiBase.php on line 418
PHP Stack trace:
PHP 1. {main}() /usr/bin/phpunit:0
PHP 2. PHPUnit_TextUI_Command::main() /usr/bin/phpunit:46
PHP 3. PHPUnit_TextUI_Command->run() /usr/share/php/PHPUnit/TextUI/Command.php:125
PHP 4. PHPUnit_TextUI_TestRunner->doRun() /usr/share/php/PHPUnit/TextUI/Command.php:187
PHP 5. PHP_CodeCoverage_Report_HTML->process() /usr/share/php/PHPUnit/TextUI/TestRunner.php:373
PHP 6. PHP_CodeCoverage->getReport() /usr/share/php/PHP/CodeCoverage/Report/HTML.php:133
PHP 7. PHP_CodeCoverage_Report_Factory->create() /usr/share/php/PHP/CodeCoverage.php:141
PHP 8. PHP_CodeCoverage->getData() /usr/share/php/PHP/CodeCoverage/Report/Factory.php:65
PHP 9. PHP_CodeCoverage->processUncoveredFilesFromWhitelist() /usr/share/php/PHP/CodeCoverage.php:173
PHP 10. include_once() /usr/share/php/PHP/CodeCoverage.php:516
PHP 11. YiiBase::autoload() /home/hijarian/systems/yii/framework/YiiBase.php:0
PHP Warning: include(): Failed opening 'CButtonColumn.php' for inclusion (include_path='.:/home/hijarian/projects/lexgarant/webapp/protected/components:/home/hijarian/projects/lexgarant/webapp/protected/models:/usr/share/php:/usr/share/pear') in /home/hijarian/systems/yii/framework/YiiBase.php on line 418
PHP Stack trace:
PHP 1. {main}() /usr/bin/phpunit:0
PHP 2. PHPUnit_TextUI_Command::main() /usr/bin/phpunit:46
PHP 3. PHPUnit_TextUI_Command->run() /usr/share/php/PHPUnit/TextUI/Command.php:125
PHP 4. PHPUnit_TextUI_TestRunner->doRun() /usr/share/php/PHPUnit/TextUI/Command.php:187
PHP 5. PHP_CodeCoverage_Report_HTML->process() /usr/share/php/PHPUnit/TextUI/TestRunner.php:373
PHP 6. PHP_CodeCoverage->getReport() /usr/share/php/PHP/CodeCoverage/Report/HTML.php:133
PHP 7. PHP_CodeCoverage_Report_Factory->create() /usr/share/php/PHP/CodeCoverage.php:141
PHP 8. PHP_CodeCoverage->getData() /usr/share/php/PHP/CodeCoverage/Report/Factory.php:65
PHP 9. PHP_CodeCoverage->processUncoveredFilesFromWhitelist() /usr/share/php/PHP/CodeCoverage.php:173
PHP 10. include_once() /usr/share/php/PHP/CodeCoverage.php:516
PHP 11. YiiBase::autoload() /home/hijarian/systems/yii/framework/YiiBase.php:0
PHP Fatal error: Class 'CButtonColumn' not found in /home/hijarian/projects/lexgarant/webapp/protected/components/CLexgarantButtonColumn.php on line 4
PHP Stack trace:
PHP 1. {main}() /usr/bin/phpunit:0
PHP 2. PHPUnit_TextUI_Command::main() /usr/bin/phpunit:46
PHP 3. PHPUnit_TextUI_Command->run() /usr/share/php/PHPUnit/TextUI/Command.php:125
PHP 4. PHPUnit_TextUI_TestRunner->doRun() /usr/share/php/PHPUnit/TextUI/Command.php:187
PHP 5. PHP_CodeCoverage_Report_HTML->process() /usr/share/php/PHPUnit/TextUI/TestRunner.php:373
PHP 6. PHP_CodeCoverage->getReport() /usr/share/php/PHP/CodeCoverage/Report/HTML.php:133
PHP 7. PHP_CodeCoverage_Report_Factory->create() /usr/share/php/PHP/CodeCoverage.php:141
PHP 8. PHP_CodeCoverage->getData() /usr/share/php/PHP/CodeCoverage/Report/Factory.php:65
PHP 9. PHP_CodeCoverage->processUncoveredFilesFromWhitelist() /usr/share/php/PHP/CodeCoverage.php:173
PHP 10. include_once() /usr/share/php/PHP/CodeCoverage.php:516
(这本身就很有趣,为什么有三个几乎相同的错误而不是只有一个。)当addUncoveredFilesFromWhitelist="false"
代码覆盖率成功生成时,当然,没有测试未覆盖的文件。
Yii框架的文件放在$HOME/systems/yii/
目录中。
我试图覆盖的应用程序放在$HOME/projects/$APPNAME/
中。
这是我的phpunit.xml
:
<phpunit bootstrap="bootstrap.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
stopOnFailure="false">
<filter>
<!-- DO NOT SET TO "true" CODE COVERAGE WILL BREAK -->
<whitelist addUncoveredFilesFromWhitelist="false">
<directory suffix=".php">..</directory>
<exclude>
<directory suffix=".php">../config/</directory>
<directory suffix=".php">../messages/</directory>
<directory suffix=".php">../tests/</directory>
<directory suffix=".php">../runtime/</directory>
<directory suffix=".php">/home/hijarian/systems/yii/framework/</directory>
</exclude>
</whitelist>
</filter>
<logging>
<log type="coverage-html"
target="report/html"
title="Lexgarant Online"
charset="UTF-8"
yui="true"
highlight="true"
lowUpperBound="35" highLowerBound="70" />
</logging>
<testsuites>
<testsuite name="All_Unit_Tests">
<directory>./unit/models/</directory>
<directory>./unit/logic/</directory>
<directory>./unit/components/</directory>
</testsuite>
</testsuites>
<selenium>
<browser name="Firefox" browser="*firefox" />
</selenium>
</phpunit>
我将所有测试都放在应用程序目录中的protected/tests
目录下,如Yii最终指南中的测试环境设置中所述。
PHPUnit调用如下:
cd $APPDIR/protected/tests/
phpunit
单元测试本身进行得很顺利,只有代码覆盖率中断。
也许我应该设置exlude列表来排除Yii类的目录,但我有点害怕这种体验,因为有几十个文件夹,Yii是一个高度模块化的系统。当然,如果这是唯一的解决方案。。。
编辑:所以,为了好奇,完整的解决方案看起来是这样的:
phpunit.xml
<php>
<!-- HACK -->
<includePath>YIIPATH/framework/zii/widgets/grid</includePath>
</php>
<filter>
<whitelist addUncoveredFilesFromWhitelist="true">
<directory suffix=".php">../models/</directory>
<directory suffix=".php">../components/</directory>
<!-- any other directories you want to check -->
</whitelist>
</filter>
只需将YIPATH占位符替换为Yii框架的真实路径。
它肯定与CButtonColumn
有关,但现在我只是在includePath
中使用这个破解,并对此感到高兴。删除这个破解会让整个bug活起来。
发生这种情况的原因:
PHPUnit将对白名单中的所有文件执行require
/include
,如果您告诉它执行addUncoveredFilesFromWhitelist="true"
。
如果这些文件包含可执行代码,它将被执行,并且您看到了出现问题的结果。
该怎么办
- 从白名单中排除所有包含可执行代码的文件
这是一个小麻烦,但它工作
- 修复include路径,使include/request调用不会破坏任何内容
我不知道为什么会出现这些错误,但这似乎是一个包含路径问题?这个框架应该有办法解决这个问题。
- PHPUnit 3.7将提供一个";生成覆盖范围,但不通过include";查看文件的模式;猜测;可执行的行
最白和代码覆盖率报告应该只包括您正在测试的文件。假设您不是为Yii框架本身编写测试,请将其从最白的框架中删除。这不仅有望解决问题,而且报告将更快地构建。