一、代码覆盖率生成工具gcov

1.1.gcov工具简介

gcov是代码覆盖率测试工具,与GCC一同使用,且只能用于GCC编译程序,其具有以下功能。

  • 统计C/C++程序某行代码执行次数。
  • 统计C/C++程序哪些代码被执行过。

说明:通常生成代码覆盖率信息需要配合单元测试工具(gtest)使用,配合单元测试发现哪些代码/分支被有效执行。

1.2.gcov工具使用

当使用gcov工具时,你必须在编译文件时使用参数--coverage,这会告诉编译器去嵌入多余代码段,生成gcov工具需要的信息。

当编译程序时,<sourcefile>.gcno文件将生成于当前目录(等同于编译时使用参数-ftest-coverage)。

当运行程序时,<sourcefile>.gcda文件将会生成于当前目录(等同于编译时使用参数-fprofile-arcs)。

gcov需要上述两个文件来生成相关的代码覆盖率信息。

总结:

  • .gcda文件在程序执行后生成,该程序编译时需要加入参数-fprofile-arcs
  • .gcno文件在编译程序时生成,该程序编译时需要加入参数-ftest-coverage
  • 编译时添加参数--coverage等同于-fprofile-arcs -ftest-coverage

1.3.gcov使用示例

首先我们创建一个名test.cppC++源文件(插入排序)。

/* FILENAME : test.cpp */
#include <iostream>
#include <algorithm>
#include <vector>

template<class It>
using value_type_t = typename std::iterator_traits<It>::value_type;

template<class It, class Compare = std::less<value_type_t<It>>>
void InsertionSort(It begin, It end, Compare cmp = Compare()) {
    for(auto it = begin; it != end; it = std::next(it)) {
        auto const insertion = std::upper_bound(begin, it, *it, cmp);
        std::rotate(insertion, it, std::next(it));
    }
}

int main(int argc, char *argv[]) {
    std::vector<int> arr = {8,3,4,0,5,1,2,9,7,6};
    InsertionSort(arr.begin(), arr.end());
    for(int i : arr) {
        std::cout << i << " ";
    }
    std::cout << std::endl;
    return 0;
}

生成可执行文件$ g++ -o test test.cpp --coverage,此时会产生成test.gcno文件。

运行程序$ ./test,此时会产生test.gcda文件。

使用命令$ gcov test.gcda生成test.cpp.gcov文件。

/* test.cpp.gcov */
 -:    0:Source:test.cpp                 
 -:    0:Graph:test.gcno            
 -:    0:Data:test.gcda
 -:    0:Runs:1
 -:    0:Programs:1
 -:    1:#include <iostream>
 -:    2:#include <algorithm>
 -:    3:#include <vector>
 -:    4:
 -:    5:template<class It>
 -:    6:using value_type_t = typename std::iterator_traits<It>::value_type;
 -:    7:
 -:    8:template<class It, class Compare = std::less<value_type_t<It>>>
 1:    9:void InsertionSort(It begin, It end, Compare cmp = Compare()) {
11:   10:    for(auto it = begin; it != end; it = std::next(it)) {
10:   11:        auto const insertion = std::upper_bound(begin, it, *it, cmp);
10:   12:        std::rotate(insertion, it, std::next(it));
 -:   13:    }
 1:   14:}
 -:   15:
 1:   16:int main(int argc, char *argv[]) {
 1:   17:    std::vector<int> arr = {8,3,4,0,5,1,2,9,7,6};
 1:   18:    InsertionSort(arr.begin(), arr.end());
11:   19:    for(int i : arr) {
10:   20:        std::cout << i << " ";
 -:   21:    }
 1:   22:    std::cout << std::endl;
 1:   23:    return 0;
 -:   24:}

二、代码覆盖率生成工具lcov

2.1.lcov工具简介

lcovGCOV的图形化前端工具集,其主要包含工具如下:

  • lcov - 获取LCOV覆盖率数据
  • genhtml - 将LCOV覆盖率数据生成HTML文件

2.2.lcov工具示例

通过gcov工具,生成如下覆盖率统计文件:

test          - 可执行文件
test.cpp      - 源代码
test.cpp.gcov - gcov工具产生文件
test.gcda      - 运行test后参数统计数据
test.gcno     - 编译test后参数统计数据

使用lcov生成LCOV覆盖率数据文件:

$ lcov --directory ./ --capture --output-file test.info

删除LCOV覆盖率数据中统计到的库文件:

$lcov --remove test.info '/usr/local/*' --output-file test.info

  • --directory - .gcda文件所在目录
  • --capture - 统计覆盖率数据
  • --output-file - 输出LCOV覆盖率数据的文件名
  • --remove - 删除LCOV覆盖率数据中不需要统计的文件名

使用genhtml工具生成html页面:

$ genhtml test.info --output-directory result

  • --output-directory - 生成html文件夹名

三、参考链接

Last modification:March 2nd, 2020 at 05:06 pm