我认为这个问题可能违反了网站的一些问答标准,因为我可能收到的答案可能被视为意见驱动的。尽管如此,它来了......
假设我们正在开发一个 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
完成工作。我想有些人会说“当然,你今天不需要灵活性,但谁知道明天呢?”。这对我来说似乎违反直觉,试图预览系统可能遇到的所有可能场景,但话又说回来,那里的人比我有更多的经验。
有什么想法吗?