Hansen's ink

Back

单元测试#

Gcov是一个测试覆盖程序,是集成在GCC中的,随GCC一起发布。

基本概念#

基本块BB#

基本块指一段程序的第一条语句被执行过一次后,这段程序中的每一跳语句都需要执行一次,称为基本块,因此基本块中的所有语句的执行次数是相同的,一般由多个顺序执行语句后边跟一个跳转语句组成

跳转ARC#

从一个BB到另外一个BB的跳转叫做一个ARC,要想知道程序中的每个语句和分支的执行次数,就必须知道每个BBARC的执行次数

程序流图#

如果把BB作为一个节点,这样一个函数中的所有BB就构成了一个有向图,要想知道程序中的每个语句和分支的执行次数,就必须知道每个BBARC的执行次数,根据图论可以知道有向图中BB的入度和出度是相同的,所以只要知道了部分的BB或者ARC大小,就可以推断所有的大小,这里选择由ARC的执行次数来推断BB的执行次数,所以对部分ARC插桩,只要满足可以统计出来所有的BBARC的执行次数即可

原理#

测试程序首先进行编译预处理,生成汇编文件,并完成插桩,插桩的过程中会向源文件的末尾插入一个静态数组,数组的大小就是这个源文件中桩点的个数,数组的值就是桩点的执行次数,每个桩点插入3~4条汇编语句,直接插入生成的*.s文件中,最后汇编文件经过汇编生成目标文件,在程序运行过程中桩点负责收集程序的执行信息

使用#

编译#

测试代码如下: say.c:

#include <stdio.h>

int say(char *what) {
    printf("------ %s\n", what);
    return 0;
}
c

main.c:

#include <stdio.h>

extern int say(const char *);

int main(int argc, const char *argv[]) {

 if (argv[1]) {
	 say("hello");
 } else {
	 say("bye");
 }
 return 0;
}
c

添加-fprofile-arcs -ftest-coverage -fPIC编译参数编译程序,生成可执行程序和*.gcno文件,里面记录了行信息和程序流图信息:

$ gcc -fprofile-arcs -ftest-coverage -fPIC -O0 say.c main.c

$ ls
a.out  main.c  main.gcno  say.c  say.gcno
sh

数据收集#

运行可执行文件,生成*.gcda在默认生成在相应*.o文件目录,里面记录了*.c文件中程序的执行情况,包括跳变次数等:

 $ ./a.out
 ------ bye
 ​
 $ ls
 a.out  main.c  main.gcda  main.gcno  say.c  say.gcda  say.gcno
sh

报告生成#

针对某一个文件的执行情况,可以通过如下命令生成报告,并创建*.gcov文件:

$ gcov -a main.c
File 'main.c'
Lines executed:80.00% of 5
Creating 'main.c.gcov'
sh

常用选项,更多可参考Invoking gcov

 -b:分支覆盖
 -a:所有基本块覆盖
 -f:函数覆盖
plaintext

注意事项#

  1. 在编译时不要加优化选项,否则代码会发生变化,无法准确定位
  2. 代码中复杂的宏,比如宏展开后是循环或者其他控制结构,可以用内联函数来代替,因为gcov只统计宏调用出现的那一行
  3. 代码每一行最好只有一条语句
  4. *.gcno*.gcda需要匹配,两个文件是有时间戳来记录是不是匹配的
  5. 若是编译动态库,需要在链接时-lgcov

图形化展示#

gcov生成的报告分散在各个源码文件所对应的*.gcov文件中,难以汇总分析,并且可视化效果较差,所以需要转化成可视图形化报告,有lcovgcovr两个工具可以完成,两者功能基本相同,gcovr,是一个用Python编写的开源软件,大小只有几十KB.

列表形式#

  1. 代码覆盖率
$ gcovr -r .
------------------------------------------------------------------------------
                           GCC Code Coverage Report
Directory: .
------------------------------------------------------------------------------
File                                       Lines    Exec  Cover   Missing
------------------------------------------------------------------------------
main.c                                         5       4    80%   15
say.c                                          3       3   100%
------------------------------------------------------------------------------
TOTAL                                          8       7    87%
------------------------------------------------------------------------------
sh

报告展示程序运行后覆盖了80%的代码

  1. 分支覆盖率
$ gcovr -b -r .
------------------------------------------------------------------------------
                           GCC Code Coverage Report
Directory: .
------------------------------------------------------------------------------
File                                    Branches   Taken  Cover   Missing
------------------------------------------------------------------------------
main.c                                         2       1    50%   14
say.c                                          0       0    --%
------------------------------------------------------------------------------
TOTAL                                          2       1    50%
------------------------------------------------------------------------------
sh

报告展示了在main.c中有一个分支没有执行到

HTML文件形式#

$ gcovr -r . --html -o xxx.html
$ ls
a.out  main.c  main.gcda  main.gcno  say.c  say.gcda  say.gcno  xxx.html
sh

可以发现添加--html参数后,可以生成html文件,用浏览器打开,如下图: gcovr_xxx.png

还可以添加--html-details选项,为每个代码文件单独生成html

$ gcovr -r . --html --html-details -o xxx.html
$ ls
a.out  main.c  main.gcda  main.gcno  say.c  say.gcda  say.gcno  xxx.html  xxx.main.c.html  xxx.say.c.html
sh

可以发现多了xxx.main.c.htmlxxx.say.c.html,用浏览器打开xxx.html,如下图: gcovr_xxx_detail.png 文件名较之前带上了下划线,单击文件名,可以看到具体的代码覆盖情况,如下图: gcovr_xxx_main.png|612

测试样例生成#

当前的大型商用代码测试软件包括了测试样例自动生成,调研了老牌的测试软件Parasoft C/C++ test与国产新推出的测试工具wings。

对比方面wingsC/C++ test
测试样例生成灵活性可以根据需求,修改赋值次数基于Google Test框架,一次性生成固定组值
测试类型见下方表格见下方表格
生成方式基于xml的值填充基于Google Test框架的测试样例代码
应用范围国产替代,使用较少市场占比极大
获取难易使用依赖于厂家的数据库格式,需要厂家提供转换插件,获取难度大有破解版,可用

image-20250222144740738|221

软件测试
https://ink.willimt.com/blog/software-test
Author Hansen W.
Published at June 4, 2025
Comment seems to stuck. Try to refresh?✨