使用GCOV统计代码覆盖率
发布时间:2019-11-01 12:30:18.278 文章来源:AiSoftCloud 浏览次数:1529 下载次数:1 

GCOV 简介

gcov 是一个能统计代码覆盖率的工具,是 GCC 编译器的一部分,不需要单独下载安装,可以统计每一行代码是否执行、执行次数、执行时间,统计出 C/C++ 程序的语句覆盖和分支覆盖情况。

gcov 只在使用GCC编译的代码上工作。它与任何其他概要或测试覆盖机制不兼容。

GCOV 使用方法

1、在编译命令上添加编译选项 -fprofile-arcs -ftest-coverage

2、编译源程序

3、运行程序

4、使用 gcov 查看代码覆盖率

GCOV 示例程序(C++)

创建类 GcovTest,如下:

头文件 gcov_test.h :

  1. #ifndef GCOV_TEST_H_
  2. #define GCOV_TEST_H_
  3. #include <string>
  4. class GcovTest {
  5. public:
  6. GcovTest();
  7. ~GcovTest();
  8. public:
  9. void Print(const std::string& message);
  10. };
  11. #endif

源文件 gcov_test.cc :

  1. #include "gcov_test.h"
  2. #include <stdio.h>
  3. GcovTest::GcovTest() {}
  4. GcovTest::~GcovTest() {}
  5. void GcovTest::Print(const std::string& message) {
  6. printf("%s", message.c_str());
  7. }

主程序 main.cc :

  1. #include "gcov_test.h"
  2. int main(int argc, char** argv) {
  3. GcovTest gcov_test;
  4. gcov_test.Print("this is a gcov test message\n");
  5. }

CMakeLists.txt :

  1. cmake_minimum_required(VERSION 3.5.1)
  2. project(gcov_test)
  3. set(CMAKE_CXX_FLAGS "-fprofile-arcs -ftest-coverage")
  4. include_directories(gcov_test_SOURCE_DIR)
  5. add_executable(gcov_test main.cc gcov_test.cc)

在项目文件目录,创建 build 文件夹,并输入 cmake .. 命令编译:

  1. cd build
  2. cmake ..

命令行输入 find ./ -name "*.gcno",可以看到编译生成的以 .gcno 结尾的编译好的文件:

  1. find ./ -name "*.gcno"
  2. // 输出结果
  3. ./CMakeFiles/gcov_test.dir/main.cc.gcno
  4. ./CMakeFiles/gcov_test.dir/gcov_test.cc.gcno

使用 gcov 统计代码覆盖率

运行编译好的程序(要看到覆盖率等数据,需要运行程序才会生成):

  1. ./gcov_test

使用 gcov 命令生成覆盖率文件,并查看覆盖率结果:

  1. gcov ./CMakeFiles/gcov_test.dir/main.cc.gcno
  2. // 输出结果
  3. File '/home/mobvoi/github/aitool/gcov/main.cc'
  4. Lines executed:100.00% of 4
  5. Creating 'main.cc.gcov'
  6. gcov ./CMakeFiles/gcov_test.dir/gcov_test.cc.gcno
  7. // 输出结果
  8. File '/home/mobvoi/github/aitool/gcov/gcov_test.cc'
  9. Lines executed:100.00% of 5
  10. Creating 'gcov_test.cc.gcov'

从上面输出可以看到main.cc和gcov_test.cc的覆盖率均为100%,要查看对应的源文件的覆盖率,使用cat main.cc.gcov即可:

  1. cat main.cc.gcov
  2. // main.cc 文件的覆盖率统计:
  3. -: 0:Source:/home/mobvoi/github/aitool/gcov/main.cc
  4. -: 0:Graph:./CMakeFiles/gcov_test.dir/main.cc.gcno
  5. -: 0:Data:./CMakeFiles/gcov_test.dir/main.cc.gcda
  6. -: 0:Runs:2
  7. -: 0:Programs:1
  8. -: 1:#include "gcov_test.h"
  9. -: 2:
  10. 2: 3:int main(int argc, char** argv) {
  11. 4: 4: GcovTest gcov_test;
  12. 2: 5: gcov_test.Print("this is a gcov test message\n");
  13. 2: 6:}
  14. cat gcov_test.cc.gcov
  15. // gcov_test.cc 文件的覆盖率统计:
  16. -: 0:Source:/home/mobvoi/github/aitool/gcov/gcov_test.cc
  17. -: 0:Graph:./CMakeFiles/gcov_test.dir/gcov_test.cc.gcno
  18. -: 0:Data:./CMakeFiles/gcov_test.dir/gcov_test.cc.gcda
  19. -: 0:Runs:2
  20. -: 0:Programs:1
  21. -: 1:#include "gcov_test.h"
  22. -: 2:
  23. -: 3:#include <stdio.h>
  24. -: 4:
  25. 2: 5:GcovTest::GcovTest() {}
  26. -: 6:
  27. 2: 7:GcovTest::~GcovTest() {}
  28. -: 8:
  29. 2: 9:void GcovTest::Print(const std::string& message) {
  30. 2: 10: printf("%s", message.c_str());
  31. 2: 11:}
  32. -: 12:

上面结果中 “-“ 表示此行无意义,不进行统计(如注释、括号行、空行等),冒号前面的数字表示此行共运行次数,如果没有被运行到,将会显示为 “#####”

使用 lcov 生成可视化覆盖率统计文档(HTML)

首先需要安装 lcov 工具:

  1. sudo apt-get install lcov

生成可视化页面:

  1. # 初始化 lcov,收集所有生成的覆盖率文件,-c 捕获,-i 初始化,-d 应用目录,-o 输出文件名称
  2. lcov -c -d ./ -o cover.info
  3. # 合并覆盖率文件,-a 合并文件
  4. lcov -a cover.info -o total.info
  5. # 移除不需要关注的文件目录,如标准库文件
  6. lcov --remove total.info '*/usr/include/*' '*/usr/lib/*' '*/usr/lib64/*' '*/usr/local/include/*' '*/usr/local/lib/*' '*/usr/local/lib64/*' -o final.info
  7. # 生成 html 文件
  8. # 获取 git 的commit id
  9. # commit_id=$(git log | head -n1 | awk '{print $2}')
  10. # 加上项目名称和commit id
  11. # genhtml -o cover_report --legend --title "${project_name} commit SHA1:${commit_id}" --prefix=./ final.info
  12. # -o 生成的html及相关文件的目录名称,--legend 简单的统计信息说明
  13. # --title 项目名称,--prefix 将要生成的html文件的路径
  14. genhtml -o cover_report --legend --title "lcov" --prefix=./ final.info

可以看到 cover_report 下生成了index.html,用浏览器打开,如下:

覆盖率统计结果

更多文章可关注公众号
aisoftcloud