C++非原创|统计代码覆盖率

Posted KK_Yolanda

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++非原创|统计代码覆盖率相关的知识,希望对你有一定的参考价值。

网络上php代码的覆盖率统计特别多,C/C++的不多见,大概是因为c/C++的收费?不知道= =

感谢原作者,原微博地址:http://www.cnblogs.com/turtle-fly/archive/2013/01/09/2851474.html

http://ltp.sourceforge.net/coverage/lcov.php demo

 

主要操作是:1 用gcov完成对c/c++文件的覆盖;2 通过lcov生成覆盖率报告;3 集成到jenkins的自动化case(需要自己做)

本章只写最简单的应用:编译单个c文件,生成lcov报告

一  搭建环境

我是直接在linux下运行程序,因此只需安装gcov和lcov环境即可

 

  • 安装 C++ 编译环境
    • yum list gcc-c++ 
    • gcc-c++.x86_64 
      • rpm -q  gcc-c++.x86_64 检查,若有该安装包则无需安装
      • 若无则 yum list gcc-c++.x86_64
    • vim 一个cpp文件
    • #include <iostream>
      
      int main()
      {
              std::cout << "Hello Wolrd!" << std::endl;
              return 0;
      }
      

        

    •  编译为可执行文件 g++ HelloWorld.cpp -o 1.c
    • 执行 ./1.c 即可
  • 安装 gcov 环境
    • 惭愧我服务器上有,所以没有安装。版本如下:gcov -v(跟gcc绑定的)                 
  •    安装lcov环境:https://sourceforge.net/projects/ltp/ 可下载不同版本
  • cd /usr/local
    wget http://sourceforge.net/projects/ltp/files/Coverage%20Analysis/LCOV-1.12/lcov-1.12.tar.gz
    tar -xzvf lcov-1.12.tar.gz
    cd lcov-1.12
    make install
    lcov -v   查看版本:lcov: LCOV version 1.12 即安装成功
    不需要编译,直接安装。lcov, gendesc, genhtml, geninfo, genpng将被安装到/usr/bin目录。

     

二   编写一个简单的c文件。文件名 fib.c(斐波那契数列)

 1 #include <stdio.h>
 2 int fibonacci(int n);
 3 
 4 int main ()
 5 {
 6    int fib;
 7    int n;
 8 
 9    for (n = 0; n <= 10; n++) {
10       fib = fibonacci(n);
11       printf("fibonnaci(%d) = %d\\n", n, fib);
12    }
13 
14    return 0;
15 }
16 
17 int fibonacci(int n)
18 {
19    int fib;
20    if (n <= 0) {
21       fib = 0;
22    }
23    else if (n == 1) {
24       fib = 1;
25    }
26    else {
27       fib = fibonacci(n -1) + fibonacci(n - 2);
28    }
29 
30    return fib;
31 }

三 gcov覆盖代码

1. 编译:gcc -c fib.c -ftest-coverage -fprofile-arcs

  检查发现生成了fib.gcno和fib.o文件,即正确

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

2 链接:以下三者择一即可,生成可执行文件fib 

gcc fib.o -o fib --coverage //我用的这个
gcc fib.o -o fib -lgcov
gcc fib.o -o fib -fprofile-arcs

3 运行fib:./fib

 

   生成gcda文件,.gcda是由加了-fprofile-arcs编译参数的编译后的文件运行所产生的,它包含了弧跳变的次数和其他的概要信息。见附1

4 生成gcov报告:gcov fib.c

  生成的fib.c.gcov文件包含了代码覆盖的统计数据,数字代表每行代码被执行的次数及行号。   

  1         -:    0:Source:fib.c
  2         -:    0:Graph:fib.gcno
  3         -:    0:Data:fib.gcda
  4         -:    0:Runs:1
  5         -:    0:Programs:1
  6         -:    1:#include <stdio.h>
  7         -:    2:
  8         -:    3:int fibonacci(int n);
  9         -:    4:
 10         1:    5:int main ()
 11         -:    6:{
 12         -:    7:   int fib;
 13         -:    8:   int n;
 14         -:    9:
 15        12:   10:   for (n = 0; n <= 10; n++) {
 16        11:   11:      fib = fibonacci(n);
 17        11:   12:      printf("fibonnaci(%d) = %d\\n", n, fib);
 18         -:   13:   }
 19         -:   14:
 20         1:   15:   return 0;
 21         -:   16:}
 22         -:   17:
 23       453:   18:int fibonacci(int n)
 24         -:   19:{
 25         -:   20:   int fib;
 26       453:   21:   if (n <= 0) {
 27        89:   22:      fib = 0;
 28         -:   23:   }
 29       364:   24:   else if (n == 1) {
 30       143:   25:      fib = 1;
 31         -:   26:   }
 32         -:   27:   else {
 33       221:   28:      fib = fibonacci(n -1) + fibonacci(n - 2);
 34         -:   29:   }
 35         -:   30:
 36       453:   31:   return fib;
 37         -:   32:}

man

四 lcov整理覆盖率数据

1. 使用已生成的.gcon .gcda文件生成覆盖率数据fib.info文件    lcov -c -o fib.info -d .

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

       -o 输出文件,后面跟目标文件

       -d 源文件.gcno .gcda所在文件夹,此处为\'.\'意为当前文件夹

[mobdev@ip-*** gtest]$lcov -c -o fib.info -d .
Capturing coverage data from .
Found gcov version: 4.8.3
Scanning . for .gcda files ...
Found 1 data files in .
Processing fib.gcda
Finished .info-file creation  //表示成功

2. 生成html格式的报告: genhtml fib.info -o fib_result

   即将文件fib.info生成html输出到fig_result文件夹内   

[mobdev@ip-*** gtest]$genhtml fib.info -o fib_result
Reading data file fib.info
Found 1 entries.
Found common filename prefix "***cppTest"
Writing .css and .png files.
Generating output.
Processing file gtest/fib.c
Writing directory view page.
Overall coverage rate:
  lines......: 100.0% (12 of 12 lines)  //代码逻辑行覆盖率
  functions..: 100.0% (2 of 2 functions)//代码方法覆盖率

3 压缩文件下载到windows系统,并打开查看网页版   

tar cvf fib_result.tar.gz fib_result/
sz  fib_result.tar.gz   //下载windows路径
在windows路径下,解压tar.gz文件,进入路径,在浏览器打开index.html如下图 

 

五  问题

1 执行lcov命令时,报错"Out of memory!",生成的fib.info文件夹为空。是因为版本不匹配

解决:查看版本如下,需要更新lcov的版本。1.10以上的lcov才支持4.8的gcov

[user@ip-******* gtest]$gcov -v
gcov (GCC) 4.8.3 20140911 (Red Hat 4.8.3-9)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.

[user@ip-******* gtest]$lcov -v
lcov: LCOV version 1.9

2 注意 gcc 只能编译 C 文件,编译 C++ 文件会报错 

Fib.o:(.eh_frame+0x12): undefined reference to `__gxx_personality_v0\'
collect2: ld 返回 1

编写一个C++文件,则在操作的第二步时更换为如下文件及命令

Fib.cpp 文件(源码相同)

编译: g++ -c Fib.cpp -ftest-coverage -fprofile-arcs

链接: g++ Fib.o -o Fib --coverage

运行:./Fib

 之后步骤相同,生成文件及各项检查均相同

 

 

 

附件为编译的各个文件的解析。

 

Linux平台代码覆盖率测试工具GCOV相关文件分析

 

附1 od -t x4 -w16 fib.gcda

http://www.linuxidc.com/Linux/2011-05/36537.htm

 

以上是关于C++非原创|统计代码覆盖率的主要内容,如果未能解决你的问题,请参考以下文章

C++统计代码覆盖率

python统计c++源程序文件中不重复代码行数

ROS系统C++代码测试之gtest

这些 C++ 代码片段有啥作用?

以下代码片段 C++ 的说明

有趣的 C++ 代码片段,有啥解释吗? [复制]