一、概述

代码覆盖率(Code coverage)是衡量软件测试质量的一个重要指标。

它描述了当一个特定的测试套件(test suite)运行时,程序源代码被执行的程度。例如,一些更具体的覆盖率指标有:

  1. Statement Coverage:描述源代码中有哪些代码行被执行,各自被执行了多少次
  2. Branch coverage:一般用于描述 if 语句 / 或其它条件语句的各分支的执行情况
  3. Function coverage:顾名思义,描述源代码中有哪些函数被执行了
  4. ······

代码覆盖率测试工具可以帮助我们发现代码中未被测试的部分,

而 gcov 则是一款和 GCC 配套发布的[经典]代码覆盖率分析工具(仅仅是对覆盖率信息文件进行分析)。

同为代码覆盖率分析工具,GCOV&LCOV&GCOVR 之间的差异:

  • GCOV:与 GCC 配套,不需要安装,生成纯文本文件
  • LCOV:需要安装,跨平台麻烦,生成 HTML 页面
  • GCOVR:需要安装,跨平台容易,且指令比 LCOV 少,生成 HTML 页面

PS. 不仅仅是 C 或者 C++,GCC所支持的语言它们应该都是支持的,例如说Fortran

二、关于 gcov 的安装

gcov 是随 gcc 一起发布的,并不需要独立安装,设法装上 gcc 就 OK 了。对于 WINDOWS 系统,通过MinGW安装 gcc 相关的组件即可使用 gcov。而对于 Linux 系统而言,通常会默认安装 gcc,因此一般不需要自己安装。

三、代码覆盖率测试(以 GCOV 为例)

首先,我们需要通过 gcc 的编译选项获取覆盖率信息文件(例如每行代码被执行了多少次啊),

这里的 “生成覆盖率信息” 的步骤对任何一个覆盖率分析工具都是完全一样的,

然后,用 gcov 收集、分析覆盖率信息文件并生成代码覆盖率报告。

用于演示的 C 程序源代码(包含一个计算阶乘的函数):

  1. #include <stdio.h>
  2. int factorial(int n);
  3. int main()
  4. {
  5. int result0 = factorial(0);
  6. int result1 = factorial(1);
  7. int result2 = factorial(10);
  8. if (result0 != 1) printf("test0 failed, actual=%d.\n", result0);
  9. if (result1 != 1) printf("test1 failed, actual=%d.\n", result1);
  10. if (result2 != 3628800) printf("test2 failed, actual=%d.\n", result2);
  11. return 0;
  12. }
  13. int factorial(int n)
  14. {
  15. if (n < 0) {
  16. printf("Factorial is defined only for non-negative integer numbers.");
  17. return -1;
  18. }
  19. if (n > 1) {
  20. return n * factorial(n - 1);
  21. } else {
  22. return 1;
  23. }
  24. }

1、编译源代码

要生成覆盖率信息文件,必须添加以下编译选项:

gcc -f**profile-arcs** -f**test-coverage** factorial.c

将 factorial.c 编译之后,我们将得到一个被“改造”过的可执行程序 a.exe(linux系统则是a.out),该程序中包含了一些额外的指令,用于记录程序中每一行被执行的次数。以及一个后缀为. gcno的 factorial.gcno 文件,它是即将被 gcov 引用的关键数据文件。

编译选项说明:

  • -ftest-coverage 选项:添加记录单行代码执行次数的指令
  • -fprofile-arc 选项:添加程序每个分支的检测代码(if 或者其它条件语句)

2、运行可执行程序

./a.exe

运行可执行程序之后,我们会得到一个factorial.gcda的文件,它和factorial.gcno一样是即将被 gcov 引用的数据文件(代码覆盖率信息文件)。

3、通过 gcov 命令生成代码覆盖率报告

  1. gcov factorial.c
  2. File 'factorial.c'
  3. Lines executed:86.67% of 15
  4. Creating 'factorial.c.gcov'

执行指令后,gcov 会引用之前的数据文件生成一个代码覆盖率报告factorial.c.gcov

  1. $ cat factorial.c.gcov
  2. -: 0:Source:factorial.c
  3. -: 0:Graph:factorial.gcno
  4. -: 0:Data:factorial.gcda
  5. -: 0:Runs:1
  6. -: 0:Programs:1
  7. -: 1:#include <stdio.h>
  8. -: 2:
  9. -: 3:int factorial(int n);
  10. -: 4:
  11. 1: 5:int main()
  12. -: 6:{
  13. 1: 7: int result0 = factorial(0);
  14. 1: 8: int result1 = factorial(1);
  15. 1: 9: int result2 = factorial(10);
  16. -: 10:
  17. 1: 11: if (result0 != 1) printf("test0 failed, actual=%d.\n", result0);
  18. 1: 12: if (result1 != 1) printf("test1 failed, actual=%d.\n", result1);
  19. 1: 13: if (result2 != 3628800) printf("test2 failed, actual=%d.\n", result2);
  20. -: 14:
  21. 1: 15: return 0;
  22. -: 16:}
  23. -: 17:
  24. 12: 18:int factorial(int n)
  25. -: 19:{
  26. 12: 20: if (n < 0) {
  27. #####: 21: printf("Factorial is defined only for non-negative integer numbers.");
  28. #####: 22: return -1;
  29. -: 23: }
  30. -: 24:
  31. 12: 25: if (n > 1) {
  32. 9: 26: return n * factorial(n - 1);
  33. -: 27: } else {
  34. 3: 28: return 1;
  35. -: 29: }
  36. -: 30:}

“#####” 所标记的是未被执行的语句。

四、生成更全面、直观的代码覆盖率报告

直接用 gcov 生成的代码覆盖率报告并不是很直观,因此一般应该都是用以下两款。

1、LCOV

Lcov 是 gcov 的图形化前端,它和 GCOV 做的工作是差不多的,只不过最后输出的是 HTML 页面形式的代码覆盖率报告。

GCOV%26LCOV%26GCOVR入门 - 图1

Ubuntu 系统下安装 LCOV:

sudo apt-get install lcov

依然用之前的 factorial.c 演示。首先,按之前的步骤生成相关数据文件,例如 xxx.gcda、xxx.gcno(PS. 不需要用 gcov 生成 xxx.c.gcov 文件)。然后,用 LCOV 收集相关数据并生成一个. info 文件(方便起见直接在当前目录执行该命令):

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

最后,通过 genhtml 将 coverage.info 转化为 HTML 文件(genhtml 是 lcov 自带的工具):

**genhtml** coverage.info --output-directory out

生成的 OUT 目录里包含了 HTML 版的代码覆盖率报告。

在 WINDOWS 上安装 LCOV 比较繁琐,有人专门写了 Windows 上可运行的 LCOV 脚本[LCOV for Windows],但是我下载下来后没弄懂怎么用。

2、GCOVR

相比于 LCOV,gcovr 可能更方便一点。LCOV 有的功能 gcovr 都有,并且 gcovr 也是开源的:https://github.com/gcovr/gcovr。它是用 Python 写的,这意味着只要有 Python 环境都可以使用 gcovr,无论是 WINDOWS 还是 LINUX。直接通过 pip(Python 的包管理工具)安装 GCOVR:

pip install gcovr

还是和之前一样的步骤生成相关的代码覆盖率信息文件,然后直接用 gcovr 生成 HTML 代码覆盖率报告就行了:

**gcovr** -r . --html --html-details -o coverage.html

GCOV%26LCOV%26GCOVR入门 - 图2

五、参考

原文:
https://www.cnblogs.com/xkxf/p/10607500.html