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

C++ 使用GTest和GMock进行测试:共享库与静态库,c++,unit-testing,architecture,googletest,gmock,C++,Unit Testing,Architecture,Googletest,Gmock,我认为这个问题可能违反了网站的一些问答标准,因为我可能收到的答案可能被视为意见驱动的。尽管如此,事情还是发生了 假设我们正在使用C++项目,使用CGube来驱动构建/测试/打包过程,以及GTest和GMOCK进行测试。进一步假设我们项目的结构如下所示: cool_project | |-- source | | | |-- module_foo | | | | | |-- (bunch of source files) | | | |-- module_bar | | | |-- (yet mo

我认为这个问题可能违反了网站的一些问答标准,因为我可能收到的答案可能被视为意见驱动的。尽管如此,事情还是发生了

假设我们正在使用C++项目,使用CGube来驱动构建/测试/打包过程,以及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\u属性
将测试的工作目录设置为库的目录。但是,如果GTest和GMock都构建为共享库,那么这将不起作用,因为它们也需要加载

我提出的解决方案是:

  • 将两个库(即GTest和GMock)复制到模块的构建目录。这感觉有点愚蠢,因为共享库的主要好处(即在程序之间共享代码)被完全忽略了,我们最终在构建目录中找到了这些库的多个副本
  • 将GTest和GMock构建为静态库。这意味着我们现在在每个可执行文件中都有两个库的副本,这会增加其大小。尽管我们没有1000次测试,但这感觉有些尴尬
因此,在这种情况下,我想知道是否有人曾经被它击中,他/她走了什么道路。(如果解决方案不是我提到的,我会很高兴听到这一切。)理想情况下,我希望自己能够
make&&make test
并运行所有的测试,而不必运行任何额外的脚本来适应事情。将所有库构建为静态库就可以了,但是如果我将它们构建为共享库呢?我必须造两次吗?那太傻了

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

在这里,模拟似乎是正确的做法,但不知何故,我觉得重构
模块\u foo
以使其与接口通信(无论是动态多态还是静态多态)没有多大意义,因为它不需要这样的灵活性:
library_baz
完成这项工作。我想有些人会说‘当然,你今天不需要灵活性,但谁知道明天呢?’。这对我来说似乎是违反直觉的,试图预览一个系统可能遇到的所有可能的场景,但话说回来,有些人比我有更多的经验

有什么想法吗?

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

只需将所有需要运行的二进制构建工件和依赖项复制(或直接在中创建)到
/bin
目录中即可


然后,您可以从这个
/bin
目录执行任何可执行文件,所有共享库都在那里。

我好像想用核导弹杀死蚊子

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

因此,总结一下:

  • GTest和GMock都构建为静态库
  • 包含我正在测试的功能的库也是如此
  • 然后将测试链接到这些目录,这样就可以运行,而不会影响工作目录

这种设置没有明显的缺点。每当我想给整个系统一个尝试,我只是切换到共享库。

你会考虑安装<代码> gTest< /COD>和<代码> GMOCK < /C>作为系统上的本地共享库,即在<代码> /Ur/Studio/LIB < /代码>中吗?如果
ldconfig
搜索路径正常,则动态链接将在那里找到它们,然后您可以将
-lgtest-lgmock-pthread
添加到测试的链接选项中。是否有一些原因不适合您的测试设置?首先,很抱歉(非常)晚的回复。这个设置不是这个问题的完美解决方案的原因是,理想情况下,我希望将测试与应用程序一起部署,并且我不想强迫用户安装一些他们可能不知道的东西。这是有道理的,但是我认为在构建一个启用了测试并遵循您的建议的项目时,会在
bin
目录中生成大量二进制文件,因为我使用的是CTest,每个测试基本上都是一个可执行文件。无论如何,谢谢你的回答。@faranwath-注意,我不建议使用任何全局
/bin
目录。只需
…/my\u project\u dir/bin
。这应该足够了,不是吗?当然,我只是想看看是否有人知道如何避免这样做,但我的希望完全是基于个人而非实际问题。正如我所说的,你的答案确实有帮助。@faranwath-在一个目录中有许多测试可执行文件有什么问题?我不完全确定我们为什么要一直讨论这个问题,但这里是这样的:这绝对没有问题,事实上,这可能是我将来选择的解决方案。我只是想将每个测试可执行文件放在与它所测试的模块相关联的目录中