当前使用遗留代码库创建许多 Pybind 模块并通过 Python 测试测试大部分公开的 C++ 代码。
是否可以通过Python测试确定C++代码的代码覆盖率?我对 C++ 覆盖率的理解是,您需要有一个已编译的测试可执行文件,其中包含可以运行的目标文件,以便收集覆盖率数据(生成的
gcda
文件)。这里的问题是 Python 测试不调用测试可执行文件,它们通过 Pybind 模块使用编译后的 .so
文件。
是否可以通过 Pybind 和
.so
文件生成覆盖率数据?
如果有帮助的话,我们正在使用 Bazel,我创建了一个简单的沙箱环境,其中包含基本的
pybind_library
目标和 py_test
目标。我可以使用覆盖标志编译 pybind_library
(包装 cc_binary
目标)并生成 gcno
文件,但是当 py_test
目标执行时,它不会生成任何 gcda
文件,但肯定会使用已编译的 .so
库。
注意:所有这些都是基于互联网上的阅读。我在这个具体问题上没有经验(gcov 由 python 测试驱动的动态库)。
我对这个问题的最初想法是不可能的,因为:
gcov 仅适用于使用 GCC 编译的代码。它与任何其他分析或测试覆盖机制不兼容
通常,当应用程序退出时,gcov 信息将存储到 .gcda 文件中。每个翻译单元都有一个文件用于分析或测试覆盖率。函数 __gcov_exit() 将 gcov 信息存储到文件中,由全局析构函数为每个用于分析或测试覆盖率的翻译单元调用。它在进程退出时运行。
要实现这一点,您需要让整个测试覆盖应用程序(您的案例中的 Python 测试)知道如何收集 gcov 信息并将其存储在 .gcda 文件中。这是通过将库 (.so) 链接到 Python 测试时在链接时传递的
--coverage
选项来完成的。如果您的链接器无法做到这一点(不知道 --coverage
选项),那么您就完成了。
--coverage
选项传递给链接器,如本文中所述:Is it possible codecoverage of a共享库使用gcov?出于所有这些原因,我相信你想要实现的目标是不可能的。
但是,帖子从Python脚本在共享库上运行gcov表明有一种方法可以实现你想要做的事情。一些曲目可以帮助您找到方向:
确保任何地方绝对没有 .gcda 文件。尝试这样做的人最终在其他地方找到了 .gcda 文件(在 .lib 目录中,其中 .so 文件而不是源文件)。例如,请参阅 gcov 从共享库生成 gcda 输出 和 此线程
在构建 Python 绑定时,不要忘记在 CPPFLAGS 和 LDFLAGS 中添加
--coverage
选项。
我们需要有关您的设置的更多详细信息才能继续。到目前为止我只能说这么多。