10. LCOV增强报告:安装LCOV、生成HTML覆盖率报告、解读报告

覆盖率数据光看终端输出,说实话,不够直观。你想想看,几百个源文件,哪个函数没测到,哪一行代码是红的——光靠眼睛扫,太累了。我个人的习惯是,一定要生成一份HTML报告,点开就能看,红绿分明,一目了然。LCOV就是干这个的。

10.1 什么是LCOV

LCOV是GCOV的图形化前端工具。它把GCOV生成的原始数据,转化成带颜色的HTML页面。说白了,就是给覆盖率数据穿上了一件漂亮的外衣。

GCOV只能输出文本文件,比如.gcov.gcda.gcno。你手动翻这些文件,效率很低。LCOV把这些文件汇总,生成一个.info文件,再通过genhtml命令,生成一套完整的HTML报告。

我在项目中遇到过好几次,客户要求提供覆盖率报告。直接给文本?不行,人家要的是网页版,能点开看的那种。LCOV就是标准答案。

10.2 安装LCOV

安装很简单。不同系统命令略有不同,但核心都一样。

Ubuntu/Debian

sudo apt-get install lcov

CentOS/RHEL

sudo yum install lcov

macOS (Homebrew)

brew install lcov

装完之后,验证一下:

lcov --version

如果输出版本号,就说明装好了。嗯,这里要注意,LCOV版本太老的话,可能不支持某些新特性。我建议装最新版,至少1.14以上。

10.3 生成HTML覆盖率报告

生成报告分三步走。第一步,编译时加覆盖率选项;第二步,运行测试用例;第三步,用LCOV生成报告。

第一步:编译加选项

跟GCOV一样,编译和链接都要加-fprofile-arcs -ftest-coverage。也可以用--coverage,效果一样。

gcc --coverage -o test_program test.c

第二步:运行测试

运行你的测试程序,生成.gcda文件。

./test_program

第三步:生成报告

先收集覆盖率数据,生成.info文件:

lcov --capture --directory . --output-file coverage.info

然后生成HTML报告:

genhtml coverage.info --output-directory coverage_report

执行完后,coverage_report目录下就有index.html了。用浏览器打开,就能看到完整的覆盖率报告。

小提示: 如果项目中包含第三方库或系统头文件,你不想统计它们。可以用--exclude参数过滤掉。比如:
lcov --capture --directory . --output-file coverage.info \
     --exclude '/usr/*'
这样报告里就只显示你自己的代码了。

10.4 解读覆盖率报告

报告打开后,你会看到几个关键指标。我带你一个一个看。

10.4.1 概览页面

首页显示所有源文件的汇总。主要看这几个数字:

指标 含义 我的经验
Lines 行覆盖率 最常用的指标。低于80%就要警惕了。
Functions 函数覆盖率 看看有没有整个函数没被调用。
Branches 分支覆盖率 if-else、switch-case有没有全覆盖。

每个文件旁边都有一个进度条。绿色表示覆盖率高,红色表示低。一眼就能看出哪些文件是“重灾区”。

10.4.2 文件详情页

点击某个文件名,进入详情页。这里能看到每一行代码的覆盖情况:

  • 绿色行:被执行过。
  • 红色行:没被执行过。
  • 黄色行:部分覆盖(比如分支语句只走了其中一个分支)。

我曾经在一个项目中,发现某个函数覆盖率一直是0%。点进去一看,原来是一个错误处理分支,测试用例从来没触发过。后来补了一个异常输入,覆盖率就上去了。

10.4.3 分支覆盖详解

分支覆盖是很多新手容易忽略的点。你想想看,一个if (a && b),其实有4种组合。如果只测了a=true, b=true,那其他3种情况都是未覆盖的。

LCOV报告里,分支覆盖会用类似2/4这样的数字表示。分子是覆盖到的分支数,分母是总分

注意: 分支覆盖不等于条件覆盖。LCOV统计的是分支跳转,不是每个条件的真值组合。如果你需要更细粒度的分析,可以考虑用其他工具配合。

10.5 实用技巧与避坑

做覆盖率报告,有几个坑我踩过,分享给你。

10.5.1 清理旧数据

每次重新生成报告前,最好清理一下旧的.gcda文件。否则旧数据会和新数据混在一起,导致结果不准。

lcov --zerocounters --directory .

10.5.2 合并多个测试的覆盖率

如果你有多个测试用例,分别运行后,可以合并它们的覆盖率数据。

lcov --add-tracefile test1.info --add-tracefile test2.info \
     --output-file total.info

这样就能看到所有测试用例加在一起的覆盖率了。

10.5.3 忽略不重要的文件

有些文件你不想统计,比如自动生成的代码、测试框架本身。用--ignore-errors可以跳过错误,用--exclude可以排除文件。

lcov --capture --directory . --output-file coverage.info \
     --exclude '*/test/*' --exclude '*/mocks/*'

10.5.4 生成报告时指定标题

默认标题是“LCOV - code coverage report”。你可以改成自己的项目名。

genhtml coverage.info --output-directory coverage_report \
     --title "MyProject Coverage Report"

10.6 知识体系图

下面这张图,帮你理清LCOV的工作流程和核心概念。

LCOV 覆盖率报告生成流程 编译加选项 -fprofile-arcs -ftest-coverage 运行测试用例 生成 .gcda 文件 lcov 收集 生成 .info 文件 genhtml 生成 HTML 报告 解读报告 行/函数/分支覆盖率 常用参数 --capture : 收集覆盖率 --directory : 指定目录 --exclude : 排除文件 --add-tracefile : 合并数据 --output-file : 输出文件名

10.7 总结

LCOV是GCOV的最佳搭档。它把枯燥的文本数据,变成了直观的HTML报告。我个人觉得,做单元测试如果没有覆盖率报告,就像开车没有仪表盘——你根本不知道车跑得怎么样。

记住几个关键点:

  • 安装简单,一条命令搞定。
  • 三步生成报告:编译、运行、lcov+genhtml。
  • 解读报告时,重点关注红色行和未覆盖的分支。
  • 善用--exclude--add-tracefile,让报告更干净。

好了,这一章就到这里。拿起你的项目,试试生成一份HTML覆盖率报告吧。看到红绿分明的那一刻,你会觉得之前的努力都值了。

核心命令速记:
lcov --capture --directory . --output-file coverage.info
genhtml coverage.info --output-directory report
公众号:蓝海资料掘金营,微信deep3321