我想了解在 C++ 中设计可测试应用程序的最佳方式,也许与 C# 相比(因为它是我的背景并且非常适合测试)
我习惯于对接口(interface)、依赖项注入(inject)、控制框架的反转和模拟对象进行编码。由于 C# 有很多不同的语言特性,我不确定有多少模式仍然适用。我还认为 C++ 的独特功能/限制可能会导致不同的测试策略。
我看过单元测试框架,我喜欢 Google Test ,但编写新代码以使其尽可能可测试也很重要。
- 是否有任何开源项目可以推荐为 C++ 测试做对了吗?
- 有没有更详细地讨论这个主题的书籍或文章?
- 对其他框架/库的建议
谢谢
最佳答案
我自己现在也处于完全相同的情况。来自 C# 背景,现在我正在编写新的(和扩展遗留的)C++ 应用程序。
我想共同的背景给我们留下了共同的问题。我很惊讶遗留应用程序中我们的类的依赖关系如此紧密。
正如您似乎强调的那样,担心的是 C# 中的最佳实践可能不是 C++ 中的最佳方法。经过大量研究、我自己提出的一些 Stack Overflow 问题以及一些原型(prototype)设计,我最终得到了一个 C++ 架构,它在很多方面反射(reflect)了我认为在 C# 中最有效的架构。
以下是我使用的主要原则:
依赖注入(inject)
我们类的构造函数采用我们可能希望模拟为参数的依赖项的接口(interface)。在某些情况下,这意味着为依赖项编写包装器,例如 boost::filesystem,它主要在模板化 header 中实现。在我看来,值得付出一点努力,因为它更松散地将我们与可能被我们更改或交换的库耦合在一起,并且它允许我们使用模拟实现进行单元测试。
随时测试!
这应该是不言而喻的,但是在编写类时编写测试可以让您在可测试性方面全面检查您的设计。我不在乎你先测试,做 TDD,或者你怎么调用它,我的理念是在你开始在你的代码库中使用类之前编写你的测试。
Google Test 作为我们的单元测试框架
到目前为止,我已经使用了 Cxxtest(遗留应用程序)和 Google Test。 Google Test 在执行时提供了很多灵活的选项来确定您运行的测试集。我们将类命名约定拆分为 UnitTest_xxxx 和 IntegrationTest_xxxx。然后在命令行中,我可以告诉 gtest 只运行具有一个名称、另一个名称或两者的测试。然后我的构建服务器可以在晚上对整个测试套件执行长时间运行的测试,但在每次 checkin 时进行单元测试。Cxxtest 可以做同样的事情,但需要更多的工作,并且由于多种原因通常很笨重。
在测试时用于模拟对象的 Google Mock
依赖注入(inject)的明显好处是在测试期间使用模拟对象。可以简单地编写每个接口(interface)的假实现,但 Google Mock 允许快速启动假对象并提供典型的检查,您期望从一个好的 .NET 模拟框架(如 Moq 或 RhinoMock)中获得。
关于c# - C++ 中的可测试性设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9678035/