PHP 单元测试覆盖率
由于绩效中写到了代码的单元测试覆盖率,于是就准备在每次需求上线前导出下覆盖率报告,就有了下面的配置。
首先,覆盖率的统计需要用到扩展 xdebug
,所以先安装下:
pecl install xdebug
可能需要手动添加
zend_extension=xdebug.so
这里给出一份我本地的测试。目录结构是这样的:
├── app
│ └── Demo.php
├── composer.json
├── composer.lock
├── phpunit.xml
├── test-result
│ └── report
│ ├── Demo.php.html
│ ├── dashboard.html
│ └── index.html
└── tests
└── DemoTest.php
phpunitx.xml的配置内容如下:
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.3/phpunit.xsd"
bootstrap="./vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnError="true"
stopOnFailure="true"
stopOnIncomplete="false"
stopOnSkipped="false"
stopOnRisky="false"
verbose="false">
<testsuites>
<testsuite name="TestSuite">
<directory>./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist addUncoveredFilesFromWhitelist="true" processUncoveredFilesFromWhitelist="true">
<file>./app/Demo.php</file>
</whitelist>
</filter>
<logging>
<log type="coverage-html" target="./test-result/report" lowUpperBound="35"
highLowerBound="70"/>
</logging>
</phpunit>
composer.json
文件内容如下:
{
"require": {
"phpunit/phpunit": "^7.5"
},
"autoload": {
"psr-4": {
"App\\": "./app",
"Test\\": "./tests"
}
}
}
App/Demo.php
文件内容如下:
<?php
namespace App;
class Demo
{
public function demo1($status)
{
if ($status == 1) {
return '未支付';
} else if ($status == 2) {
return '等待支付';
} else {
return '已支付';
}
}
public function demo2()
{
return 123;
}
}
DemoTest.php
文件内容如下:
<?php
namespace Test;
use App\Demo;
use PHPUnit\Framework\TestCase;
class DemoTest extends TestCase
{
/**
* @covers \App\Demo::demo1
*/
public function testDemo1()
{
$result = (new Demo)->demo1(1);
$this->assertEquals('未支付', $result);
$result = (new Demo)->demo1(2);
$this->assertEquals('等待支付', $result);
$result = (new Demo)->demo1(3);
$this->assertEquals('已支付', $result);
}
}
上面这些是一个简单的单元测试,这里注意下 phpunit.xml
的配置,其中的 filter
中的标签是开启单元测试的覆盖率分析,其中设置了哪些文件需要分析覆盖率。 logging
标签里面配置了单元测试覆盖率报告,报告格式有很多,我这里选择了 html 格式,便于直接查看。接下来,我们可以跑下:
~ learn-phpunit ./vendor/bin/phpunit
PHPUnit 7.5.2 by Sebastian Bergmann and contributors.
. 1 / 1 (100%)
Time: 51 ms, Memory: 4.00MB
OK (1 test, 3 assertions)
Generating code coverage report in HTML format ... done
测试成功,我们打开 test-result/report/index.html
文件,可以看到:
点击 Demo.php
可以看到
到这里,单元测试覆盖率的导出基本上就可以使用了。但是,还有一个问题,在团队开发当中,很多时候我们只是编写了一个文件中的部分代码,那么如果我们只想对这部分代码进行覆盖率测试,该怎么办呢?
这里我们可以利用 @codeCoverageIgnoreStart
和 @codeCoverageIgnoreEnd
两个标签。例如上,上面的 Demo.php
文件,我们只想对 demo1
方法的覆盖率进行统计,于是我们可以这么做:
<?php
namespace App;
class Demo
{
public function demo1($status)
{
if ($status == 1) {
return '未支付';
} else if ($status == 2) {
return '等待支付';
} else {
return '已支付';
}
}
// @codeCoverageIgnoreStart
public function demo2()
{
return 123;
}
// @codeCoverageIgnoreEnd
}
用这两个标签将不需要分析的代码包裹起来就可以啦。我们来看下覆盖率分析报表:
OK,就到这里了。
======
本作品采用《CC 协议》,转载必须注明作者和本文链接
高认可度评论:
拓展一下,可使用 Coveralls 等服务对测试覆盖率进行收集,例如我的项目:https://github.com/wi1dcard/alipay-sdk-php
集成 CI 后,可在每次执行单元测试时将报告提交至 Coveralls。我使用 Travis CI,配置如下:
在
after_script
内,下载 Coveralls 的 PHAR,随后执行该 PHAR 包,即可采集位于build/logs/clover.xml
的测试覆盖率报告,并上传至 Coveralls 了。欲生成该 XML 格式的测试报告文件,可使用
phpunit --coverage-clover build/logs/clover.xml
。或在
phpunit.xml
内配置如下内容:拓展一下,可使用 Coveralls 等服务对测试覆盖率进行收集,例如我的项目:https://github.com/wi1dcard/alipay-sdk-php
集成 CI 后,可在每次执行单元测试时将报告提交至 Coveralls。我使用 Travis CI,配置如下:
在
after_script
内,下载 Coveralls 的 PHAR,随后执行该 PHAR 包,即可采集位于build/logs/clover.xml
的测试覆盖率报告,并上传至 Coveralls 了。欲生成该 XML 格式的测试报告文件,可使用
phpunit --coverage-clover build/logs/clover.xml
。或在
phpunit.xml
内配置如下内容: