使用GTest和GMock进行测试:共享库和静态库

时间:2014-01-20 15:06:28

标签: c++ unit-testing architecture googletest gmock

我认为这个问题可能会违反网站的部分Q& A标准,因为我可能会收到的答案可能被视为意见驱动。不过,这里...... ...

假设我们正在开发一个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,即使它可能正在测试不相关的功能。出现同样的问题。

Mocking在这里似乎是正确的做法,但不知怎的,我认为重构module_foo以便它与界面交谈(无论是动态还是静态)都没有多大意义多态性)因为它不需要这样的灵活性:library_baz完成工作。我想有些人会说'当然,你今天不需要灵活性,但明天谁知道?'。这对我来说似乎是违反直觉的,试图预测一个系统可能遇到的所有可能情况,但是再一次,那里的人有比我更多的经验。

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

我似乎试图用核导弹杀死蚊子。

我提出的解决方案是在测试时将所有库构建为静态对象。是的,我最终得到了相当大的二进制文件,但事实并非如此,我将分发这些文件。

所以,总结一下:

  • GTest和GMock都是作为静态库构建的。
  • 包含我正在测试的功能的库也一样。
  • 测试然后链接到那些,因此可以在不弄乱工作目录的情况下运行。

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

答案 1 :(得分:0)

我认为这样做(至少在Windows上,我不在* nix上开发)完全独立于任何测试:

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

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