是否可以将来自两个可执行文件的覆盖率数据与 gcov/gcovr 合并?

Posted

技术标签:

【中文标题】是否可以将来自两个可执行文件的覆盖率数据与 gcov/gcovr 合并?【英文标题】:Is it possible to merge coverage data from two executables with gcov/gcovr? 【发布时间】:2015-08-30 05:38:41 【问题描述】:

在一个项目中,我在三个不同的可执行文件上运行测试用例,并使用不同的选项进行编译。根据选项,是否采用某些代码路径。现在,我只使用一个可执行文件的覆盖率数据。

我正在使用 gcovr 生成一个 XML,然后由 Sonar 解析:

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

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

有没有办法做到这一点?

【问题讨论】:

lcov 就是这样做的。因此,来自 lcov 项目的人可能会有所帮助。 @k0n3ru,lcov 以某种中间格式合并数据。 lcov 的问题是我没有 XML Cobertura 格式了。 @BaptisteWicht 可能的解决方法是,如果您的项目可以使用 lcov ,似乎有 lcov 到 cobertura xml 转换器。 当您说您使用不同的选项进行编译时:您是指不同的编译器选项(例如一次使用-o2,另一次使用-o3),还是定义不同的预处理器宏?或者甚至是别的什么? 【参考方案1】:

假设“使用不同的选项编译”是指在 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;

sut.h 只提供 foo 的声明,以及 test.c 中的一个简单的 main,它调用 foo 并打印结果。然后,通过这一系列命令,我能够创建一个 100% 覆盖 sut.c 的 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 显示以下结果:

编辑(感谢 Gluttton 提醒我添加这部分内容):在此处提供的“lcov to cobertura XML 转换器”的帮助下,应该可以从 lcov 格式的 total.info 文件到 Cobertura XML 输出(虽然我没试过):https://github.com/eriwen/lcov-to-cobertura-xml

但是,可以合并覆盖率信息这一事实当然并不意味着这样做是一个好主意:IMO 覆盖率对于测试套件的质量只有有限的信息价值。合并来自不同预处理器输出的覆盖率结果甚至会进一步降低该值。

这是因为开发人员了解他们没有考虑过的场景的可能性会降低:通过使用条件编译,代码的控制结构和数据流可能会在预处理器输出之间发生巨大差异 - 覆盖信息由“覆盖”产生不同预处理器输出的测试运行结果可能无法对结果进行有意义的解释。

【讨论】:

但是如何将报告从html 转换为xml (Cobertura) 格式? 您宁愿将 lcov 的 .info 格式直接转换为 cobertura。谷歌搜索把我带到了这里:github.com/eriwen/lcov-to-cobertura-xml 谢谢。我刚刚尝试过,它确实适用于合并 gcov 数据,但我还没有找到将 lcov 数据转换为 cobertura 的好方法。我尝试了提到的工具,但是它丢弃了很多信息,生成的xml中没有分支信息。 @baptiste-wicht:在这种情况下,我建议向他们发送错误报告,因为 a) README.md 声称他们可以处理“线路和分支命中”和 b) CHANGELOG.md声称从 1.1 版(当前版本为 1.6)开始提供 Branch“覆盖报告”。

以上是关于是否可以将来自两个可执行文件的覆盖率数据与 gcov/gcovr 合并?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以访问可执行 JAR 之外的 SQLite 数据库文件?

重新分配/覆盖热键 (Win + L) 以锁定窗口

可以让 gcc/gcov 将覆盖率统计信息输出到源文件夹以外的位置吗?

是否可以将 Electron 应用程序和数据文件嵌入到单个可执行文件中?

Makefile:来自相同源的两个目标使用不同的标志编译两次

是否可以在没有代码覆盖率工具作为入口点的情况下收集代码覆盖率数据?