我想了解用C ++设计可测试应用程序的最佳方法,也许与C#相比(因为它是我的背景,非常适合测试)
我习惯于编码接口,依赖注入,控制框架的反转和模拟对象。由于C#有很多不同的语言特性,我不确定有多少模式仍然适用。我还想象C ++的独特功能/限制可能会带来不同的测试策略。
我已经查看了单元测试框架,我喜欢Google Test,但是编写新代码以使其尽可能可测试也很重要。
由于
答案 0 :(得分:4)
我现在处于完全相同的情况。来自C#背景,现在我正在编写新的(并扩展遗留的)C ++应用程序。
我猜共享背景给我们留下了常见问题。令我感到惊讶的是,遗留应用程序中的依赖关系与我们的类紧密相关。
正如您似乎强调的那样,关注点可能是C#中的最佳实践并不是C ++中最好的方法。经过大量研究,我自己的一些Stack Overflow问题以及一些原型设计,我最终得到了一个C ++架构,它在很多方面反映了我在C#中最好的效果。
以下是我正在使用的主要原则:
依赖注入
我们的类的构造函数接受我们可能想要作为参数模拟的依赖项的接口。在某些情况下,这意味着为依赖项编写包装器,例如boost :: filesystem,它主要在模板化头文件中实现。在我看来,值得花费很少的努力,因为我们可以更加松散地将我们与可能改变或被我们交换的库耦合在一起,并且它允许我们使用模拟实现进行单元测试。
随时测试!
这应该不言而喻,但是在编写课程时编写测试可以让您在可测试性方面检查您的设计。我不在乎你先测试,做TDD,或者你称之为什么,我的理念是在开始在代码库中使用类之前编写测试。
Google Test作为我们的单元测试框架
到目前为止,我使用过Cxxtest(遗留应用)和Google Test。 Google Test在执行时提供了许多灵活的选项,以确定您运行的测试集。我们将类命名约定分为UnitTest_xxxx和IntegrationTest_xxxx。然后在命令行,我可以告诉gtest只运行一个名称,另一个或两者的测试。然后我的构建服务器可以在晚上对整个测试套件执行长时间运行的测试,但是每次检查都要进行单元测试.Cxxtest可以做同样的事情,但是工作量更多,而且由于很多原因而且通常很笨拙。
Google Mock for test object at test time
依赖注入的明显好处是在测试期间使用模拟对象。人们可以简单地编写每个界面的虚假实现,但Google Mock允许快速旋转虚假对象,并提供您期望从一个好的.NET模拟框架(如Moq或RhinoMock)进行的典型检查。
答案 1 :(得分:2)
我使用了CPP Unit这是JUnit的一个端口。它非常易于使用,并以XML格式提供输出,非常棒。至于如何使用它,你可以check out the cookbook here.
答案 2 :(得分:1)
在某些情况下,我已经看到你提到的所有技术(编码接口,依赖注入,控制框架的反转和模拟对象)被滥用并最终使事情变得更难。虽然这些技术可以很好地使用,但有时我看到它们被传播,好像它们是通往质量的唯一途径。我不同意。
从我的角度来看,保证C ++代码质量的最重要的开发技术是使用面向对象技术,如模块化,开放原则,自我文档,命令查询分离,等
特别是,我认为必不可少的两种技术是按合同设计(请参阅问题What is the best way of implementing assertion checking in C++?和Design by Contract in C++?)和单元测试(查看相关问题1,2,3)。对于他们两个,你有合理的C ++工具,因为链接的问题显示。
答案 3 :(得分:0)
我可以推荐UnitTest++和AMOP进行测试驱动开发。两者都很容易设置,非常强大。如果您不需要Google Test中的所有功能,这是一个不错的选择。
它们可能看起来已经过时了,因为它们暂时没有更新,但我没有遇到任何问题。