序
本文介绍的代码覆盖率检查方式只适用于gcc编译器,因为使用的检查工具gcov和lcov都是gcc自带,其他编译器不一定有,但是检查覆盖率的方法是通用的,具备借鉴性。
环境准备
- 一份可以编译通过的代码
- 一台linux服务器
- 服务器上安装gcc编译器,不论什么类型,只要支持gcov和lcov就行,系统自带的也可以(本文以操作系统自带的为例)
代码如下:
#include <stdio.h> int add(int a, int b) { int ret = 0; ret = a + b; return ret; } int division(int a, int b) { int ret = 0.0; if(b == 0) { ret = -1; } else { ret = a / b; } return ret; } int main() { printf("1 + 2 = %d ", add(1, 2)); printf("4 / 2 = %d ", division(4, 2)); return 0; }
检查流程
第一步:编译
gcc -fprofile-arcs -ftest-coverage main.c -o main
-fprofile-arcs -ftest-coverage 这两编译参数必须添加,添加这两个编译参数之后,会生成.gcno的文件,这种文件是后续检查代码复杂度必须的文件
第二步:运行
./main
直接运行代码即可,在代码的运行过程会生成.gcda的文件,这种文件也是后续检查代码复杂度必须的文件
第三步:gcov
gcov main.c
使用gcov工具计算覆盖率,需要依赖.gcno文件和.gcda文件,会生成.gcov文件,该文件中就包含代码的覆盖率信息,执行命令的输出如下:
File‘main.c’ 已执行的行数:92.86% (共 14 行) Creating 'main.c.gcov'
该命令会直接打印出覆盖率,打开main.c.gcov文件如下所示:
-: 0:Source:main.c -: 0:Graph:main.gcno -: 0:Data:main.gcda -: 0:Runs:1 -: 0:Programs:1 -: 1:#include <stdio.h> -: 2: 1: 3:int add(int a, int b) -: 4:{ 1: 5: int ret = 0; -: 6: 1: 7: ret = a + b; -: 8: 1: 9: return ret; -: 10:} -: 11: 1: 12:int division(int a, int b) -: 13:{ 1: 14: int ret = 0.0; -: 15: 1: 16: if(b == 0) -: 17: { #####: 18: ret = -1; -: 19: } -: 20: else -: 21: { 1: 22: ret = a / b; -: 23: } -: 24: 1: 25: return ret; -: 26:} -: 27: 1: 28:int main() -: 29:{ 1: 30: printf("1 + 2 = %d ", add(1, 2)); 1: 31: printf("4 / 2 = %d ", division(4, 2)); -: 32: 1: 33: return 0; -: 34:} -: 35:
其中 “#”开头的行表示运行main时没有覆盖的行,"1"开头的行表示运行main时覆盖的行,"-"开头的行表示忽略的行,不进行计算,执行命令时打印的覆盖率就是通过这种方法计算出来的。不难看出这种方法虽然可以计算出覆盖率,但是结果的观察方式不够令人满意,所以lcov出来了,locv的操作方法前两步和gcov相同,都是在依赖.gcno文件和.gcda文件,只是后续做了优化。
第四步:lcov
lcov -c -d . -o main.info
-c:表示成功覆盖率
-d:表示表示依赖文件坐在的目录
-o:表示目标文件的名称
main.info:该文件包含所有的覆盖率信息
第五步:genhtml
genhtml的主要作用就是将main.info中的性能可视化,命令如下:
genhtml main.info -o ./result
-o:表示输出结果的存放文件
该命令的输出结果如下所示:
Reading data file main.info Found 1 entries. Found common filename prefix "/home/coverity" Writing .css and .png files. Generating output. Processing file test/main.c Writing directory view page. Overall coverage rate: lines......: 92.9% (13 of 14 lines) functions..: 100.0% (3 of 3 functions)
该命令也会直接打印出覆盖率,这是一种查看方式,进入到刚才指定输出结果的文件夹目录result,可以看到一对html文件,是的,lcov的优势就是可以按照网页的形式查看结果,点击index.html,如下图所示:
网上可以非常直观的看到各种数据,其中不仅有行覆盖率还有函数覆盖率,且点击是按照文件夹的形式管理,直接点击就可以单独查看,实在是很方便。
总结
代码覆盖率是维护代码的一个指标,覆盖率越高越好,不过现状是代码的行覆盖率达到60%就非常非常不错了。