genhtml 使用方式及参数说明
genhtml 用于把 lcov 生成的 .info 文件转换为可浏览的 HTML 报告。它不会主动运行测试,也不会直接读取 .gcda,它只消费 lcov tracefile。
基本命令
genhtml coverage.info --output-directory coverage-html
生成后打开 coverage-html/index.html,即可查看目录、文件、行覆盖率、函数覆盖率和分支覆盖率。
常用参数
| 参数 | 说明 |
|---|---|
--output-directory DIR |
指定 HTML 输出目录 |
--title TEXT |
设置报告标题 |
--legend |
显示颜色图例 |
--show-details |
显示更详细的目录信息 |
--branch-coverage |
显示分支覆盖率 |
--function-coverage |
显示函数覆盖率 |
--demangle-cpp |
对 C++ 符号名做反混淆 |
--num-spaces N |
设置 tab 展开宽度 |
--prefix PREFIX |
移除路径前缀,使报告路径更短 |
--sort |
按覆盖率等信息排序,便于快速找到低覆盖文件 |
--no-sort |
不排序,按原路径或默认顺序展示 |
--highlight |
对源码显示做语法高亮 |
--no-highlight |
关闭源码高亮 |
--frames |
生成带 frame 的页面布局,旧式浏览体验中常见 |
--no-frames |
不生成 frame 页面 |
--quiet |
减少输出 |
--verbose |
输出更详细的处理信息 |
--validate |
检查生成的 HTML 链接和输出文件有效性 |
--css-file FILE |
使用自定义 CSS 文件 |
--description-file FILE |
为测试名称添加说明信息 |
--ignore-errors TYPE |
忽略指定错误 |
--rc KEY=VALUE |
临时覆盖 genhtml/lcov 配置项 |
参数分类
| 目的 | 常用参数 |
|---|---|
| 输出位置 | --output-directory |
| 报告标题 | --title |
| 报告可读性 | --legend、--show-details、--demangle-cpp |
| 分支和函数 | --branch-coverage、--function-coverage |
| 页面样式 | --css-file、--highlight、--frames |
| 路径显示 | --prefix |
| 排查问题 | --verbose、--validate、--ignore-errors |
示例
genhtml coverage.info \
--output-directory coverage-html \
--title "Unit Test Coverage" \
--legend \
--show-details \
--branch-coverage \
--demangle-cpp
更完整的 HTML 报告命令
genhtml coverage.info \
--output-directory coverage-html \
--title "GoogleTest Coverage" \
--legend \
--show-details \
--branch-coverage \
--function-coverage \
--demangle-cpp \
--sort \
--num-spaces 4
如果源码路径包含很长的工作区前缀,可以用 --prefix 缩短展示:
genhtml coverage.info \
--output-directory coverage-html \
--prefix "$(pwd)" \
--legend \
--show-details
--prefix 只影响报告中的路径展示,不改变 tracefile 的原始数据。
报告中的颜色含义
| 颜色 | 含义 |
|---|---|
| 绿色 | 覆盖充分 |
| 黄色 | 部分覆盖 |
| 红色 | 覆盖不足或未覆盖 |
具体阈值由 lcov/genhtml 默认设置或参数配置决定。查看报告时不要只看总百分比,还要进入关键文件观察未覆盖行是否属于错误路径、边界条件或真正无关代码。
覆盖率阈值显示
genhtml 的颜色阈值可以通过配置项调整。不同版本支持的配置项略有差异,常见写法如下:
genhtml coverage.info \
--output-directory coverage-html \
--rc genhtml_hi_limit=90 \
--rc genhtml_med_limit=75
这类阈值主要影响报告颜色,不等同于 CI 门禁。如果需要覆盖率低于某个值时让构建失败,通常使用 gcovr --fail-under-line,或在 CI 脚本中解析 lcov 摘要。
行覆盖率、函数覆盖率和分支覆盖率
| 类型 | 含义 | 局限 |
|---|---|---|
| 行覆盖率 | 源码行是否执行过 | 一行中多个条件可能只覆盖一部分 |
| 函数覆盖率 | 函数是否被调用过 | 函数内部路径不一定充分 |
| 分支覆盖率 | 条件分支是否分别走过 | 需要编译器和 lcov 支持 |
示例:
int Clamp(int value, int low, int high) {
if (value < low) {
return low;
}
if (value > high) {
return high;
}
return value;
}
如果测试只覆盖 value < low,行覆盖率可能看起来不差,但分支和行为覆盖明显不足。应至少覆盖低于下界、高于上界、位于范围内三个场景。
与 lcov 配合的完整流程
lcov --directory build-coverage --zerocounters
ctest --test-dir build-coverage --output-on-failure
lcov --capture --directory build-coverage --output-file coverage.raw.info
lcov --remove coverage.raw.info '/usr/*' '*/_deps/*' '*/tests/*' --output-file coverage.info
genhtml coverage.info --output-directory coverage-html --legend --branch-coverage --demangle-cpp
自定义样式
如果团队希望报告具有统一样式,可以使用自定义 CSS:
genhtml coverage.info \
--output-directory coverage-html \
--css-file coverage.css
CSS 只影响展示,不改变覆盖率数据本身。CI 中归档 HTML 报告时,应同时归档自定义 CSS 文件引用到的资源。
描述文件
--description-file 可以给测试名添加说明,适合多 tracefile 合并后解释不同测试来源。
示例描述文件:
TN:unit
TD:Unit tests from GoogleTest
TN:integration
TD:Integration tests with local services
生成报告:
genhtml coverage.total.info \
--description-file coverage_descriptions.txt \
--output-directory coverage-html
如果没有使用 lcov --test-name 或 tracefile 中没有测试名,描述文件的价值不大。
校验生成结果
生成报告后可以使用 --validate 检查 HTML 输出中的链接和文件引用:
genhtml coverage.info \
--output-directory coverage-html \
--validate
这个选项更适合脚本调试和报告模板修改场景。普通本地生成报告时通常不必每次开启。
报告解读建议
- 先看整体趋势,再看核心模块。
- 优先补关键业务逻辑、边界条件和错误路径。
- 不要为了追求百分比测试无意义的 getter 和简单转发函数。
- 对不可达防御分支,可以在代码审查中说明,而不是强行制造脆弱测试。
常见问题
| 问题 | 可能原因 | 处理 |
|---|---|---|
| HTML 中源码路径很长 | tracefile 使用绝对路径 | 使用 --prefix |
| 分支列没有显示 | tracefile 没有分支数据或 genhtml 未开启 | lcov 和 genhtml 同时启用分支参数 |
| C++ 函数名难读 | 符号名未反混淆 | 使用 --demangle-cpp |
| 报告页面样式丢失 | HTML 资源未完整归档 | 归档整个输出目录 |
| 颜色阈值不符合团队标准 | 默认阈值不合适 | 使用 --rc genhtml_hi_limit 等配置 |