C代码覆盖率检查

最近在跟一个推荐系统引擎相关功能的测试,做过相关测试的同学应该知道引擎可是整套系统的核心,如果引擎系统挂了或者出现了严重bug对整个系统的影响可是无法估量的。所以为了保证引擎系统能够稳定的运行必须采用足够多的手段,所以测试中代码覆盖率可以作位一种测试是否全面的衡量标准。

由于之前没有做过相关方面的工作,所以要从头开始研究,这里把最近学习的成果做一个简单的介绍。

一、环境准备:

我是直接在Ubuntu 下运行程序,因此只需安装gcovlcov环境即可:

$ sudo apt-get install gcov

检查是否安装成功:gcov -v

$ sudo apt-get install lcov

检查是否安装成功:lcov -v

二、简单示例:

写一个简单的c++示例代码:

#include<stdio.h>

int Add(inta,int b);

int Sub(inta,int b);

int Mul(inta,int b);

int Div(inta,int b);

int main ()

{

  int a=10;

  int b=5;

  printf("%d + %d = %d\n", a, b,Add(a, b));

   return 0;

}

int Add(int a,int b)

{

return (a+b);

}

int Sub(int a,int b)

{

return (a-b);

}

int Mul(int a,int b)

{

return (a*b);

}

// 不做异常处理

int Div(int a,int b)

{

return (a/b);

}

 

正常执行一下看看运行结果:

接下来我们看看测试的代码覆盖率的实际效果

1. 编译

root@guozhenhua-OptiPlex-7010:/home/gcov_test_new# gcc -ctest.c -ftest-coverage -fprofile-arcs

root@guozhenhua-OptiPlex-7010:/home/gcov_test_new# ls

test.c  test.gcno  test.o

除了test.o 之外,还生成了 test.gcno 的话,成功了

.gcno是由-ftest-coverage产生的,它包含了重建基本块图和相应的块的源码的行号的信息。

2.生成可执行文件

gcc test.o -o test --coverage //我用的这个

gcc test.o -o test -lgcov

gcc test.o -o test -fprofile-arcs

 

root@guozhenhua-OptiPlex-7010:/home/gcov_test_new# gcc test.o-o test –coverage

执行完的效果如下:

 

运行后的效果如下:

root@guozhenhua-OptiPlex-7010:/home/gcov_test_new# ./test

10 + 5 = 15

root@guozhenhua-OptiPlex-7010:/home/gcov_test_new# ls

test  test.c  test.gcda test.gcno  test.o

 生成gcda文件,.gcda是由加了-fprofile-arcs编译参数的编译后的文件运行所产生的

 

3、生成测试结果:

执行结果如下:

root@guozhenhua-OptiPlex-7010:/home/gcov_test_new#gcov test.c

File 'test.c'

Lines executed:53.85% of 13

Creating 'test.c.gcov'

 

  生成的test.c.gcov文件包含了代码覆盖的统计数据,数字代表每行代码被执行的次数及行号。被标记为#####的代码行就是没有被执行过的,代码覆盖的信息是正确的,但是让人去读这些文字,实在是一个杯具。不用担心,开始咱们安装的另一个工具lcov还没大显身手嗯,他的本领就是用程序解析这些晦涩的字符,输出一个完美的html报告给开发

 

       -:    0:Source:test.c

       -:    0:Graph:test.gcno

       -:    0:Data:test.gcda

       -:    0:Runs:1

       -:    0:Programs:1

       -:    1:#include <stdio.h>

       -:    2:

       -:    3:int Add(int a,int b);

       -:    4:int Sub(int a,int b);

       -:    5:int Mul(int a,int b);

       -:    6:int Div(int a,int b);

       -:    7:

       -:    8:

       1:    9:int main ()

       -:   10:{

       1:   11:  int a=10;

       1:   12:  int b=5;

       -:   13: 

       1:   14:  printf("%d + %d = %d\n", a, b,Add(a, b));

       -:   15:

       1:   16:   return 0;

       -:   17:}

        -:  18:

       -:   19:

       1:   20:int Add(int a, int b)

       -:   21:{

       1:   22:return (a+b);

       -:   23:}

       -:   24:

       -:   25:

   #####:   26:int Sub(int a, int b)

       -:   27:{

   #####:   28:return (a-b);

       -:   29:}

       -:   30:

       -:   31:

   #####:   32:int Mul(int a, int b)

       -:   33:{

   #####:   34:return (a*b);

       -:   35:}

       -:   36:

       -:   37:

       -:   38:// 不做异常处理

   #####:   39:int Div(int a, int b)

       -:   40:{

   #####:   41:return (a/b);

       -:   42:}

       -:   43:

 至于 gcov 的更多选项,例如 -b 分支覆盖 -f 函数覆盖, man

 

4LCOV 使用

root@guozhenhua-OptiPlex-7010:/home/gcov_test_new#lcov -c -o test.info -d .

Capturingcoverage data from .

Found gcov version:4.9.2

Scanning . for.gcda files ...

Found 1 datafiles in .

Processingtest.gcda

Finished .info-filecreation

简单解释一下三个选项

-c: lcov 的一个操作,表示要去捕获覆盖率数据

-o: 输出文件

-d: .gcno .gcda 所在的文件夹,注意这里有个“.”,是从当前文件夹中获取数据的

生成最终的html结果:

root@guozhenhua-OptiPlex-7010:/home/gcov_test_new# genhtmltest.info -o test_result

Reading data file test.info

Found 1 entries.

Found common filename prefix "/home"

Writing .css and .png files.

Generating output.

Processing file gcov_test_new/test.c

Writing directory view page.

Overall coverage rate:

  lines......: 53.8% (7of 13 lines)

  functions..: 40.0% (2of 5 functions)

从以上结果可以看出覆盖率分为行覆盖率53.8% 函数覆盖率40.00%(把main函数也算进去了)

 

执行后多了一个文件夹:

root@guozhenhua-OptiPlex-7010:/home/gcov_test_new# ls

test  test.c  test.gcda test.gcno  test.info  test.o test_result

 

将生成的代码文件转移到apache下查看效果如下:

红色部分是未执行到的代码,蓝色部分是被执行的代码,前的数字是被执行的次数,而且最上面还有总的行覆盖率和函数覆盖率

 

后期还会分享so文件的覆盖率和外部传参的覆盖率

 

猜你喜欢

转载自blog.csdn.net/gzh0222/article/details/79348241
今日推荐