shipmonk-rnd/coverage-guard
GitHub: shipmonk-rnd/coverage-guard
一款面向 PHP 项目的 CI 代码覆盖率强制执行工具,支持按核心方法和增量新代码进行精准的覆盖率检查。
Stars: 55 | Forks: 1
# PHP Code Coverage Guard
**在 CI 中轻松强制代码覆盖率!** 不是按百分比,而是针对**核心功能**。
- 🎮 **颠覆性体验:** 创新的代码覆盖率强制执行方式!
- 💾 **对老旧代码友好:** 允许你仅从新代码开始强制执行!
- ⚙️ **可扩展:** 由你指定必须被覆盖的内容!
- 🕸️ **轻量级:** 仅依赖 `nikic/php-parser`
- 🍰 **易于使用:** 首次尝试无需配置
该工具帮助确保特定代码块被测试覆盖,通常是 Facades、Controllers 和应用程序其他关键领域的核心方法。
## 安装
```
composer require --dev shipmonk/coverage-guard
```
## 使用示例
```
# 运行测试,收集 coverage,生成报告:
XDEBUG_MODE=coverage vendor/bin/phpunit tests --coverage-filter src --coverage-clover clover.xml
# 验证 coverage:
vendor/bin/coverage-guard check clover.xml
```
### 示例输出:
在实际应用中,你可能会使用 `phpunit.xml` 来 [配置 PHPUnit 覆盖率](https://docs.phpunit.de/en/10.5/code-coverage.html#including-files):
```
src
```
要收集覆盖率,你可以选择传统的 [XDebug](https://xdebug.org/docs/install) 或高性能的 [PCOV](https://github.com/krakjoe/pcov/blob/develop/INSTALL.md) 扩展。
## 仅对新代码强制覆盖率
```
git diff master...HEAD > changes.patch
vendor/bin/coverage-guard check clover.xml --patch changes.patch
```
- 当提供 patch 时,该工具将仅分析更改的文件和方法,不会报告其他地方的违规情况。
- 这允许你逐步地仅对新代码强制执行代码覆盖率。
## 配置
- 在项目根目录中创建一个 `coverage-guard.php` 文件来自定义行为并设置你的 `CoverageRules`。
- 你可以通过 `vendor/bin/coverage-guard init` 生成一个快速入门配置
- 配置文件必须返回一个 `ShipMonk\CoverageGuard\Config` 实例
- 以下是你可以配置的内容:
```
addRule(new EnforceCoverageForMethodsRule(
requiredCoveragePercentage: 50,
minMethodChangePercentage: 50, // when --patch is provided, check only methods changed by more than 50%
minExecutableLines: 5, // only check methods with at least 5 executable lines
));
// Replace prefix of absolute paths in coverage files
// Handy if you want to reuse clover.xml generated in CI
$config->addCoveragePathMapping('/absolute/ci/prefix', __DIR__);
// As filepaths in git patches are relative to the project root, you can specify the root directory here
// It gets autodetected if cwd is inside some git repository
$config->setGitRoot(__DIR__);
// Make CLI file paths clickable to your IDE
// Available placeholders: {file}, {relFile}, {line}
$config->setEditorUrl('phpstorm://open?file={file}&line={line}');
return $config;
```
### 高级用法:
- 对于自定义强制逻辑,请实现 `CoverageRule` 并将其传递给 `Config::addRule()` 方法:
- 从现成的 [`EnforceCoverageForMethodsRule`](src/Rule/EnforceCoverageForMethodsRule.php) 或实际用例中获取灵感:
- [专属覆盖率配置](./coverage-guard.php)
- [dead-code-detector](https://github.com/shipmonk-rnd/dead-code-detector/blob/master/coverage-guard.php)
- [phpstan-rules](https://github.com/shipmonk-rnd/phpstan-rules/blob/master/coverage-guard.php)
### 你可以强制执行的内容:
传递给 `CoverageRule` 的 `CodeBlock` 类知道**哪一行是可执行的、已更改的和已覆盖的**。
此外,你可以使用**反射**来精确定位你的规则。
这使你能够设置各种各样的规则,例如:
- 所有**新创建的方法**必须有一定的覆盖率
- 当一个方法**被更改超过 50% 时**,它必须至少有 50% 的覆盖率
- 代码库中所有**超过 10 行可执行代码**的方法必须有一定的覆盖率
- 所有 **`Controller` 方法**必须至少有 50% 的覆盖率
- 每个方法都必须经过测试,除非使用了自定义的 **`#[NoCoverageAllowed]` 属性**
- ...
## 全局 CLI 选项
- `--help` 显示通用帮助(或与命令名称组合时显示命令帮助)
- `--no-color` 禁用颜色(也支持 `NO_COLOR` 环境变量)
- `--color` 即使输出不是 TTY 也强制显示颜色
运行 `vendor/bin/coverage-guard --help` 以查看特定命令的选项。
## 支持的 PHPUnit 覆盖率格式
| 格式 | 文件大小 | 评级 | 备注 |
|--------|-----------------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
| **clover** (`.xml`) | (基准) | 🟢 最佳 | 可用于 [PHPStorm 覆盖率可视化](https://www.jetbrains.com/help/phpstorm/viewing-code-coverage-results.html)。允许更好的完整性检查。 |
| **cobertura** (`.xml`) | 1.7 倍大 | 🟡 还行 | 可用于 [GitLab 覆盖率可视化](https://docs.gitlab.com/ci/testing/code_coverage/#coverage-visualization) |
| **php** (`.cov`) | 8 倍 - 40 倍大 | 🔴 避免 | 在未激活 xdebug 的旧版 PHPUnit 上可能会产生警告。良好的覆盖率很容易产生超过 100 MB 的超大文件。 |
## 命令
### `check`
- 如上所述,在你的代码库中强制执行代码覆盖率规则的主要命令。
```
vendor/bin/coverage-guard check clover.xml
```
选项:
- `--verbose` – 显示详细的处理信息
- `--patch` – git diff 的路径,仅检查更改文件和方法的覆盖率
- `--config` – 自定义 PHP 配置的路径
### `merge` & `convert`
- 将多个覆盖率文件合并为一个文件在[并行 CI 任务中运行测试](https://github.com/shipmonk-rnd/phpunit-parallel-job-balancer)时非常有用。
- 请注意,这些命令**不会保留原始 XML 中的所有数据**
- 它仅生成最小的 XML 文件,同时保持对 PHPStorm、GitLab 和 Coverage Guard 的可用性
- 输入格式:`clover`、`cobertura`、`php`(自动检测)
- 输出格式:`clover`、`cobertura`
```
vendor/bin/coverage-guard merge coverage/*.xml > merged.xml
vendor/bin/coverage-guard convert cobertura.xml --output-format clover > clover.xml
```
选项:
- `--output-format` – 输出格式(`clover` 或 `cobertura`)
- `--indent` – 输出 XML 缩进(默认为 4 个空格);如需使用制表符,请使用 `--indent=$'\t'`
- `--config` – 自定义 PHP 配置的路径
### `patch-coverage`
- 计算 patch 文件中已更改行的覆盖率百分比。
- 方便用于 [GitLab 覆盖率模式](https://docs.gitlab.com/ci/testing/code_coverage/#configure-coverage-reporting):`coverage: '/Coverage:\s+(\d+\.\d+%)/'`
- 你将在你的 MR 详情中看到已更改行的覆盖率
```
git diff master...HEAD > changes.patch
vendor/bin/coverage-guard patch-coverage clover.xml --patch changes.patch
```
选项:
- `--patch` – diff 文件的路径(必填)
- `--config` – 自定义 PHP 配置的路径
输出示例:
```
Patch Coverage Statistics:
Changed executable lines: 45
Covered lines: 38
Uncovered lines: 7
Coverage: 84.44%
```
### `init`
- 在你当前目录中生成示例 `coverage-guard.php` 配置文件。
- 你应该根据自己的需求进行自定义。
```
vendor/bin/coverage-guard init
```
## 可选依赖
- 库:
- `phpunit/php-code-coverage` 用于加载覆盖率 cov 文件
- `sebastian/diff` 用于处理 diff/patch 文件
- PHP 扩展:
- `ext-libxml` 和 `ext-simplexml` 用于加载覆盖率 XML 文件
- `ext-dom` 用于 `check` 和 `merge` 命令
- `ext-tokenizer` 用于查看语法高亮的代码块
## 贡献
- 通过 `composer check` 检查你的代码
- 通过 `composer fix:cs` 自动修复代码风格
- 所有功能都必须经过测试
在实际应用中,你可能会使用 `phpunit.xml` 来 [配置 PHPUnit 覆盖率](https://docs.phpunit.de/en/10.5/code-coverage.html#including-files):
```
标签:Anchore, ffuf, OpenVAS, PHP, PHPUnit, SOC Prime, 开发工具, 测试覆盖率