6

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

假设我们正在开发一个 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完成工作。我想有些人会说“当然,你今天不需要灵活性,但谁知道明天呢?”。这对我来说似乎违反直觉,试图预览系统可能遇到的所有可能场景,但话又说回来,那里的人比我有更多的经验。

有什么想法吗?

4

2 回答 2

2

看来我是想用核导弹杀死一只蚊子。

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

所以,总结一下:

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

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

于 2014-03-12T15:05:54.720 回答
0

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

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

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

于 2014-02-12T07:32:59.777 回答