能否使用gcov/gcovr合并来自两个可执行文件的覆盖率数据?

26

在一个项目中,我正在运行三个不同选项编译的可执行文件上的测试用例。根据选项,某些代码路径会被采取或不采取。目前,我只使用一个可执行文件的覆盖率数据。

我正在使用 gcovr 生成一个 XML 文件,然后通过 Sonar 解析:

gcovr -x -b -r . --object-directory=debug/test > coverage_report.xml

我有三组gcda和gcno文件,但是不知道如何生成它们的全局报告。

有没有什么方法可以做到这一点?


lcov可以做到这一点。因此,可能有来自lcov项目的人可以提供帮助。 - k0n3ru
@k0n3ru,使用lcov合并数据时需要一些中间格式。 - Gluttton
lcov的问题在于我不再拥有XML Cobertura格式了。 - Baptiste Wicht
@BaptisteWicht 可能的解决方法是,如果您的项目可以使用 lcov,则似乎有 lcov 到 cobertura xml 转换器。 - k0n3ru
当你说你使用不同的选项进行编译时,你是指不同的编译器选项(例如一次使用 -o2,另一次使用 -o3),还是指定义了不同的预处理宏?或者甚至是其他什么东西? - Dirk Herrmann
@DirkHerrmann 我指的是在我的代码中激活不同功能的预处理器宏。例如,我有一个启用GPU加速的宏。我对总覆盖率感兴趣:普通版本和GPU加速版本所占的总覆盖率。 - Baptiste Wicht
1个回答

14

假设你所说的“使用不同选项编译”是指在预处理后获得不同输出,我使用lcov(正如k0n3ru所提到的)就可以实现。这是文件 sut.c 中的示例代码:

#include "sut.h"
#include <limits.h>

int foo(int a) {
#if defined(ADD)
    a += 42;
#endif
#if defined(SUB)
    a -= 42;
#endif
    return a;
}

只提供foo的声明和test.c中调用foo并打印结果的简单main函数,sut.h并未提供具体实现。接着,通过以下命令序列,我能够为sut.c创建一个总覆盖率为100%的total.info文件:

> g++ --coverage -DADD test.c sut.c -o add.out
> ./add.out
> lcov -c -d . -o add.info   # save data from .gdda/.gcno into add.info
> g++ --coverage -DSUB test.c sut.c -o sub.out
> ./sub.out
> lcov -c -d . -o sub.info   # save again, this time into sub.info
> lcov -a add.info -a sub.info -o total.info  # combine them into total.info
> genhtml total.info

对于sut.c,以下是显示的结果:

enter image description here

编辑(感谢Gluttton提醒我添加这一部分):通过使用此处提供的“lcov to cobertura XML converter”,可以从以lcov格式呈现的total.info文件转换为Cobertura XML输出(尽管我尚未尝试过):https://github.com/eriwen/lcov-to-cobertura-xml

然而,能够合并覆盖信息并不意味着这么做是一个好主意:在我看来,覆盖率对于测试套件的质量只有有限的信息价值。从不同的预处理器输出中合并覆盖率结果甚至会进一步降低这个价值。

这是因为开发人员了解到他们没有考虑的情况的可能性将会减少:通过使用条件编译,代码的控制结构和数据流在预处理器输出之间可能会非常不同——从不同的预处理器输出中“叠加”测试运行结果的覆盖率信息可能会使结果的有意义解释变得不可能。


但是如何将报告从 html 转换为 xml(Cobertura)格式? - Gluttton
你最好直接将 lcov 的 .info 格式转换为 cobertura。通过谷歌搜索,我找到了这个链接:https://github.com/eriwen/lcov-to-cobertura-xml - Dirk Herrmann
谢谢。我刚试了一下,它确实可以合并gcov数据,但我还没有找到一个好的方法将lcov数据转换为cobertura格式。我尝试了提到的工具,但它们会丢失很多信息,在生成的xml中没有分支信息。 - Baptiste Wicht
在这种情况下,我建议向开发者发送一个错误报告,因为a) README.md 声称它们可以处理“行和分支命中率”,b) CHANGELOG.md 声称自版本1.1以来可用分支“覆盖率报告” (当前版本是1.6)。 - Dirk Herrmann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接