使用 GTest 和 GMock 进行测试:共享库与静态库 [英] Testing with GTest and GMock: shared vs. static libraries

查看:36
本文介绍了使用 GTest 和 GMock 进行测试:共享库与静态库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I think this question may violate some of the Q&A standards for the site, as the answer(s) I may receive could be regarded as opinion-driven. Nevertheless, here it goes...

假设我们正在处理一个 C++ 项目,使用 CMake 来驱动构建/测试/打包过程,并使用 GTest 和 GMock 进行测试.进一步假设我们项目的结构如下所示:

Suppose we're working on a C++ project, using CMake to drive the build/testing/packaging process, and GTest and GMock for testing. Further suppose the structure of our project looks like this:

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)

当然,这是一种过于简单化的情况,但您懂的.

This is, of course, an oversimplified situation, but you get the idea.

现在好了,如果这些模块是库并且每个测试(即 tests 下的每个目录)都是一个可执行文件,我们需要将后者与前者链接起来.问题是,如果这些库是共享的,加载程序当然需要找到它们.一个明显的解决方案是使用 CMake 的 set_property 将测试的工作目录设置为库的目录.但是,如果 GTest 和 GMock 也被构建为共享库,这将不起作用,因为它们也需要加载.

Now well, if these modules are libraries and every test (i.e. every directory under tests) is an executable, we need to link the latter with the former. The thing is, if these libraries are shared, the loader needs of course to find them. An obvious solution is to set the test's working directory to the library's directory, using CMake's set_property. However, if both GTest and GMock were also built as shared libraries, this won't work as they need to be also loaded.

我想出的解决方案是:

  • 将两个库(即 GTest 和 GMock)复制到模块的构建目录.这感觉有点愚蠢,因为共享库的主要好处(即在程序之间共享代码)被完全绕过了,我们最终在构建目录中得到了这些的多个副本.
  • 将 GTest 和 GMock 构建为静态库.这意味着我们现在最终将两个库的副本复制到每个可执行文件中,这会增加其大小.尽管我们没有 1000 次测试,但这感觉有点尴尬.

因此,鉴于这种情况,我想知道是否有人曾经被它击中过,以及他/她采取了哪些途径.(如果解决方案不是我提到的解决方案,我很乐意听到所有相关信息.)理想情况下,我希望处于可以 make && 的位置.make test 并运行所有测试,而无需运行任何额外的脚本来适应事物.将所有库构建为静态库就可以完成这项工作,但是如果我将它们构建为共享库呢?我必须建造它们两次吗?太傻了.

So, given this situation, I would like to know if anyone has ever been struck with it, and what path did he/she take. (If the solution was other than the ones I mentioned, I would be happy to hear all about it.) Ideally, I'd like to be in a position in which I could make && make test and have all the tests run, without having to run any extra script to accommodate things. Having all libraries built as static libraries does the job, but what if I'm building them as shared libraries instead? Must I build them twice? That's silly.

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

The other problem also runs along these lines, but I think its solution involves a redesign or a similar artifact. Let's suppose module_foo depends on a third-party library, e.g. library_baz. If module_foo links directly to library_baz, then any test on the former would need to load library_baz, even though it may be testing an unrelated functionality. Same issue arises.

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

Mocking seems like the right thing to do here, but somehow I feel it doesn't make much sense to refactor module_foo in order for it to talk to an interface (be it by virtue of either dynamic or static polymorphism) as it doesn't need such flexibility: library_baz does the job. I suppose some people would say something like 'Sure, you don't need the flexibility today, but who knows tomorrow?'. That seems counter-intuitive to me, trying to preview all possible scenarios a system may run into, but then again, there are people out there with far more experience than me.

有什么想法吗?

推荐答案

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

It seems I was trying to kill a mosquito by using a nuclear missile.

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

The solution I came up with was to simply build all libraries as static objects when testing. True, I end up with pretty big binaries, but it's not the case that I'll be distributing those.

总结一下:

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

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

There are no significant drawbacks to this setup. Whenever I want to give the entire system a try, I simply switch to shared libraries.

这篇关于使用 GTest 和 GMock 进行测试:共享库与静态库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆