使用GTEST和GMOCK进行测试:共享与静态库

Testing with GTest and GMock: shared vs. static libraries

本文关键字:共享 静态 测试 GTEST GMOCK 使用      更新时间:2023-10-16

我认为这个问题可能违反了该网站的某些Q&一个标准,因为我可能会收到的答案可以被视为意见驱动。尽管如此,它去了...

假设我们正在研究一个C 项目,使用CMAKE驱动构建/测试/包装过程,而GTEST和GMOCK进行测试。进一步假设我们项目的结构看起来像这样:

cool_project
|
|-- source
| |
| |-- module_foo
| | |
| | |-- (bunch of source files)
| |
| |-- module_bar
| |
| |-- (yet more source files)
|
|-- tests
|
|-- module_foo
| |
| |-- (tests for module_foo)
|
|-- module_bar
|
|-- (tests for module_bar)

当然,这是一个过于简单的情况,但是您明白了。

现在很好,如果这些模块是库,并且每个测试(即tests下的每个目录)都是可执行的,则我们需要将后者与前者联系起来。问题是,如果共享这些库,则当然需要加载器才能找到它们。一个明显的解决方案是使用CMAKE的set_property将测试的工作目录设置为库的目录。但是,如果GTEST和GMOCK都作为共享库构建,则该库也不起作用,因为它们也需要加载。

我想出的解决方案是:

  • 将两个库(即GTEST和GMOCK)复制到模块的构建目录。由于共享库的主要好处(即在程序之间共享代码)被完全绕过,我们最终在整个构建目录中获得了几份副本。
  • 改为将GTEST和GMOCK构建为静态库。这意味着我们现在最终将两个库的副本都纳入每个可执行文件中,从而增加了其大小。即使我们没有1000次测试,这感觉有些尴尬。

所以,在这种情况下,我想知道是否有人曾经被撞到它,以及他/她走了什么道路。(如果解决方案是我提到的解决方案,我很乐意听到所有信息。)理想情况下,我想处于我可以make && make test并进行所有测试的位置,而无需运行任何额外的脚本来容纳事物。将所有库都构建为静态库可以做到这一点,但是如果我将它们构建为共享库,该怎么办?我必须两次建造它们吗?那很愚蠢。

另一个问题也沿着这些线路运行,但我认为它的解决方案涉及重新设计或类似的工件。让我们假设module_foo取决于第三方库,例如library_baz。如果module_foo直接链接到library_baz,那么前者的任何测试都需要加载library_baz,即使它可能正在测试无关的功能。出现同样的问题。

嘲笑似乎在这里做正确的事,但是我觉得重构module_foo是没有多大意义的,以便它与界面交谈(无论是动态还是静态多态性)不需要这样的灵活性:library_baz可以完成工作。我想有些人会说诸如"确定,您今天不需要灵活性,但明天谁知道?"。这对我来说似乎是违反直觉的,试图预览系统可能遇到的所有可能的情况,但是话又说回来,那里的人比我拥有更多的经验。

有什么想法?

看来我试图使用核弹杀死蚊子。

我提出的解决方案就是在测试时简单地将所有库构建为静态对象。没错,我最终得到了很大的二进制文件,但是我会分发这些。

so,总结:

  • gtest和gmock都是静态库。
  • 对于包含我正在测试的功能的库也是如此。
  • 测试然后链接到这些链接,因此可以在不弄乱工作目录的情况下运行。

此设置没有明显的缺点。每当我想尝试整个系统时,我都只需切换到共享库。

这样,我看到了(至少在Windows上,我在 *Nix上开发)非常独立于任何测试:

简单地所有二进制构建工件和运行所需的依赖项必须复制(或直接创建)到./bin目录中。

然后,您可以从此./bin目录中执行任何可执行文件,并且所有共享库都在此处。