随着对软件质量要求的不断提高,传统黑盒测试已不能满足代码测试质量要求,覆盖率能够让开发/测试人员清晰的看到代码运行覆盖状况,不断的调整测试策略和场景,尽可能的测到所有场景,以提升软件质量。
PHP代码覆盖率通常有两种方式进行统计,一种是通过PHPUnit单元测试,编写单测用例,验证代码逻辑的正确性并输出覆盖率报告。 另一种是通过http请求接口,传入不同的请求参数,验证接口输入输出,并统计代码覆盖率。
本文讲述第二种方式,话不多说直接进入正题:
1. 前期准备
覆盖率涉及到两种插件:
① php-code-coverage
该插件库提供PHP代码覆盖率信息的收集、处理和呈现功能。其核心是提供了CodeCoverage类。
github地址:https://github.com/sebastianbergmann/php-code-coverage
② phpcov
该插件库是php-code-coverage库的命令行前端,提供生成覆盖率报告的工具,包括合并多个覆盖率文件,输出一份完整全面的覆盖率报告。
github地址:https://github.com/sebastianbergmann/phpcov
安装方法根据github中说明使用composer安装即可,如果读者的环境没有composer或者在内网无法下载获取,也可以在文章末尾下载源码,在pulgin目录中包含了这两个插件库。环境要求为: php >= 7.2
2. demo代码
① demo介绍
主要功能是接收http请求,并根据不同的url调用不同的函数,每个请求生成覆盖率文件,最终通过phpcov插件合并生成覆盖率报告。
② 目录结构
controllers - 控制器目录
plugin - 插件目录,放置php覆盖率插件库
tmp - 临时目录,覆盖率文件以及报告输出在这里
config.php - 配置文件
index.php - 入口文件,路由解析,实例化controller对象
phpcodecoverage.php - 引入插件库并调用相关功能
③ 核心代码解析
config.php
<?php
$config['enable_coverage'] = true; //覆盖率开关
$config['while_dirs'] = [ //要统计的目录
'controllers/'
];
$config['while_files'] = [ //要统计的文件
'index.php'
];
phpcodecoverage.php
<?php
require_once "config.php";
require_once "plugin/phpcode/autoload.php";
use SebastianBergmann\CodeCoverage\CodeCoverage;
use SebastianBergmann\CodeCoverage\Filter;
/**
* 定义请求结束时执行的函数
* @param CodeCoverage $coverage
* @return void
* @throws ReflectionException
*/
function __coverage_stop(CodeCoverage $coverage)
{
$coverage->stop();
//停止统计
$writer = new \SebastianBergmann\CodeCoverage\Report\PHP();
// 设置生成代码覆盖率页面的路径
$file_name = substr(md5(uniqid()), 0, 10);
//这里注意要输出为php格式,而不能输出为html格式,否则不能合并多个请求的覆盖率了。
$writer->process($coverage, dirname(__FILE__) . '/tmp/coverage/'. $file_name .'.cov');
}
if ($config['enable_coverage']) //开启开关才进行统计
{
$coverage = new CodeCoverage();
$local_dir = dirname(__FILE__);
if ($config['while_dirs'])
{
foreach ($config['while_dirs'] as $dir) //添加要统计的文件目录
{
$coverage->filter()->addDirectoryToWhitelist($local_dir.'/'.$dir);
}
}
if ($config['while_files'])
{
foreach ($config['while_files'] as $file) //添加要统计的文件
{
$coverage->filter()->addDirectoryToWhitelist($local_dir.'/'.$file);
}
}
$coverage->start('coverage'); //开始统计
register_shutdown_function('__coverage_stop', $coverage); //注册函数关闭时的回调函数
}
index.php
<?php
require_once "phpcodecoverage.php"; //引入插件
if (isset($_SERVER['PATH_INFO']))
{
if ($_SERVER['PATH_INFO'] === '/' || $_SERVER['PATH_INFO'] === '')
{
echo 'This is index';
exit;
}
else
{
$path_array = array_values(array_filter(explode('/', $_SERVER['PATH_INFO']))); //路由解析
if (empty($path_array))
{
throw new Exception('url error');
}
$ctrl = $path_array[0];
$func = $path_array[1] ?? 'index';
$file_path = 'controllers/' . $ctrl . '.php';
if (file_exists($file_path))
{
require_once $file_path;
$class = ucfirst($ctrl);
$obj = new $class();
$obj->$func();
}
}
}
else
{
echo 'This is index';
exit;
}
④ 效果展示
在页面上输入请求url:
第一次请求:
第二次请求:
此时已生成2个覆盖率文件:
⑤ 生成覆盖率报告
a) 先确保你的php客户端添加至你的系统变量中,检验方法为:打开cmd,执行 php -v
b) cd至phpcov插件库中的bin目录
c) 执行命令:php phpcov merge --html=“覆盖率报告输出目录路径” “覆盖率文件所在目录路径” -vvv
d) 成功
e) 查看效果
项目源码:
https://github.com/LYJ-jj/phpcodecoverage_demo