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

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

问题描述

我认为这个问题可能会违反网站的某些Q& A标准,因为我可能收到的答案可能被视为观点驱动.尽管如此,它在这里...

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.

在这里看起来模拟是正确的事情,但是以某种方式,我觉得重构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天全站免登陆