如何获得头文件中成员函数的正确代码覆盖率

时间:2019-03-08 07:39:53

标签: c++ code-coverage gcovr

当我运行单元测试套件后运行gcovr时,我得到错误的编号来覆盖放置一些内联成员函数定义的头文件。例如:

----------------------------------------------------------------------------  
File                                       Lines    Exec  Cover   Missing  
------------------------------------------------------------------------------   
include/analysis/dataobjects/DetailedHit.h     6       2    33%   41-43,45
include/analysis/dataobjects/Hit.h            19       0     0%   31-33,35-36,42-43,50-51,58-59,74-75,82-83,90-91,98-99

对于Hit.h,报告的覆盖率是0%,但是我确定在单元测试运行期间至少会执行该标头中的某些代码,因为如果我在其中放置一个cout,那么我会在控制台输出。在网络上,经常有人提出这是一个问题,因为编译器会内联成员函数代码,从而不会生成函数调用,因此覆盖率工具不会跟踪执行情况。所以我添加了标志:

-fno-inline -fno-inline-small-functions -fno-default-inline

调用编译器(gcc 8.2.1),但得到相同的覆盖率报告。所以我不知道发生了什么。

最让我感到困惑的是,为什么gcovr在DetailedHit.h中报告2个覆盖行。此标头与Hit.h非常相似,因此我希望报告的覆盖率为0%时具有相同的行为,但是该成员函数为:

const std::vector<Herd::ParticleHit> ParticleHits() const {
  return _particleHits;
}

结果将执行10次。这是一个简单的函数,因此应内联为Hit.h中的那些函数,但仍会被覆盖。万一重要,Hit是DetailedHit的具体基类,并且都没有虚拟方法。

我想我缺少关于gcov和gcovr的工作原理的一些重要知识,但是我在网络上找不到相关的线索,因此我希望能对此提供帮助。谢谢。

1 个答案:

答案 0 :(得分:1)

覆盖率为0%的方法是标头中的内联方法。

我确实使用gcc --coverage编译了我正在测试的库,该库用于检测机器代码以收集覆盖率。但是,我没有测试可执行文件,因为我对测试本身的覆盖范围不感兴趣。因此,测试可执行文件包含内联方法的代码,而无需进行检测。

因此,这些方法是gcov已知的,但未收集任何覆盖率(仅执行了非仪器内联版本)。

解决方案:

  • 还使用--coverage编译器标志来测试测试
  • 使用-e / --exclude gcovr选项过滤掉不必要的测试覆盖数据