【发布时间】:2014-02-09 19:40:47
【问题描述】:
我认为这个问题可能违反了网站的一些问答标准,因为我可能收到的答案可能被视为意见驱动的。不过,还是这样吧……
假设我们正在开发一个 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 完成了这项工作。我想有些人会说“当然,你今天不需要灵活性,但谁知道明天呢?”。这对我来说似乎违反直觉,试图预览系统可能遇到的所有可能场景,但话又说回来,那里的人比我更有经验。
有什么想法吗?
【问题讨论】:
-
您是否考虑将
gtest和gmock安装为系统上的本地共享库,即在/usr/local/lib中?如果您的ldconfig搜索路径正常,动态链接将在那里找到它们,然后您可以将-lgtest -lgmock -pthread添加到测试的链接选项中。是否有某些原因不适合您的测试设置? -
首先,很抱歉(非常)迟回复。此设置不能完美解决此问题的原因是,理想情况下,我希望将测试与应用程序一起部署,并且我不想强迫用户安装一些他们可能不知道的东西.
标签: c++ unit-testing architecture googletest gmock