我们正在使用 LCOV/GCOV 来生成我们项目的测试覆盖率。最近我们尝试另外启用分支覆盖。但看起来,这并没有产生我们从高级开发人员视图中预期的结果。
将分支覆盖与 C++ 一起使用会使报告在整个地方都出现分支。我们怀疑(正如搜索问题所表明的那样)大多数异常处理代码会创建这些“隐藏分支”。 GCOV/LCOV 似乎并没有跳过这些。
我创建了一个小测试项目来显示问题: https ://github.com/ghandmann/lcov-branch-coverage-weirdness
目前我们使用 Ubuntu 16.04。和:
- 海合会 v5.4
- lcov & genhtml v1.12
我们的生产代码是在启用 c++11 的情况下构建的。最小的示例不是在启用 c++11 的情况下构建的,但是当我们对所有不同的选项(c++ 标准、优化、 -fno-exceptions
)进行了一些试验时,我们没有得出一个可以接受的结果。
有人有什么想法吗?小费?我们是否以错误的方式使用任何东西?这是 - 如其他地方所述 - 真的是预期的行为吗?
更新:
正如 gcc-help 邮件列表中 所指出的那样,这些“隐藏分支”是由于异常处理而出现的。因此,添加 -fno-exceptions
切换到 gcc 会为“简单”程序产生 100% 的分支覆盖率。但是当异常被禁用时,gcc 拒绝编译实际使用异常的代码(例如try-catch、throw)。因此,对于真正的生产代码,这不是一个选项。看起来,在这种情况下,您必须简单地将 ~50% 的覆盖率声明为新的 100%。 ;)
原文由 Sven Eppler 发布,翻译遵循 CC BY-SA 4.0 许可协议
问题是 GCC 还记录每一行的分支信息,其中可能由于某些抛出的异常而退出范围(例如,在 Fedora 25 上使用 GCC 6.3.1 和 lcov 1.12)。
这些信息的价值是有限的。分支覆盖数据的主要用例是复杂的 if 语句,它们具有如下的多子句逻辑表达式:
假设您有兴趣验证您的测试套件是否也涵盖
bar > x
案例,或者您是否只有y == 0
的测试用例。为此,分支覆盖数据收集和 lcov 的 genhtml 的可视化很有用。对于简单的 if 语句,如
您不需要分支覆盖率数据,因为您可以通过查看以下几行的覆盖率来查看分支是否被采用。
由
genhtml
生成的lcov
的输入是相对简单的文本格式(参见geninfo(1)
)。因此,您可以对其进行后处理,以便删除所有以BRDA:
开头且不属于 if 语句的行。参见例如filterbr.py
它实现了这种方法。另请参阅gen-coverage.py
了解其他 lcov/genhtml 处理步骤和 将生成的跟踪文件上传到 codecov 的示例项目(codecov 不使用genhtml
但可以导入 lcov 跟踪文件和显示分支覆盖数据)。(非)替代品
-O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls
之类的东西编译会在一定程度上减少记录的分支覆盖数据的数量,但不会太多-fprofile-instr-generate -fcoverage-mapping
编译和使用llvm-profdata
和llvm-cov
进行后处理---
)。但是,该工具链不支持分支覆盖率数据(截至 2017-05-01)。--rc lcov_branch_coverage=0
和--no-branch-coverage
)