2012-03-13 58 views
7

可测性我想了解设计在C++中,可测试的应用程序也许相比于C#的最佳方法(因为它我的背景和伟大的用于测试)设计在C++

我已经习惯了编码到接口,依赖注入,控制框架的反转以及模拟对象。由于C#有很多不同的语言功能,我不确定有多少模式仍然适用。我也想象C++的独特功能/局限性可能适用于不同的测试策略。

我已经看过单元测试框架,我喜欢Google Test,但编写我的新代码以使其可测试也很重要。

  • 是否有任何开源项目可以推荐为C++ 测试做得对吗?
  • 任何有关此主题的更详细的书籍或文章?
  • 建议额外的框架/库

由于

回答

3

我现在处于完全相同的状态。来自C#的背景,现在我正在编写新的(并扩展传统的)C++应用程序。

我想共享背景给我们留下了常见的问题。我很惊讶,遗留应用程序中的依赖关系与我们的类紧密耦合。

正如您似乎已经强调的那样,担心的可能是C#中的最佳实践并不是C++中的最佳方法。经过大量研究,我自己的一些堆栈溢出问题以及一些原型,我最终得到了一个C++架构,这在很多方面反映了我在C#中最棒的工作方式。

下面是我使用的主要负责:

  • 依赖注入

    构造函数为我们班采取接口,我们可能要嘲笑作为参数的依赖关系。在某些情况下,这意味着为依赖项编写包装,例如boost :: filesystem,这主要是在模板头文件中实现的。在我看来,值得我们花费很小的努力,更松散地将我们从图书馆中耦合起来,这些图书馆可能会改变或者被我们调换,并允许我们用模拟实现进行单元测试。

  • 随你行!

    这应该不言而喻,但在您编写该类时编写测试可让您在可测试性方面对设计进行完整性检查。我不在乎你先测试,做TDD,还是不管你怎么称呼它,我的理念就是在开始在你的代码库中使用这个类之前编写你的测试。

  • 谷歌测试为我们的单元测试框架

    到目前为止,我已经使用Cxxtest(遗留应用程序)和谷歌测试。Google Test在执行时提供了很多灵活的选项来确定您运行的测试集。我们将我们的类命名约定分为UnitTest_xxxx和IntegrationTest_xxxx。然后在命令行中,我可以告诉gtest只能用一个名称,另一个或两者来运行测试。然后我的构建服务器可以在每一个检查执行,在整个测试套件在夜间长时间运行测试,但是单元测试。Cxxtest可以做同样的事情,但有更多的工作,一般是笨重的原因有很多。

  • 模拟谷歌在测试时间

    依赖注入的明显的好处是在测试过程中使用嘲笑的对象模仿对象。人们可以简单地写每个接口的假冒实现,但谷歌模拟允许快速旋转起来假冒的对象,并提供您所期望的一样起订量或RhinoMock良好的.NET模拟框架典型的检查。

1

在某些场合,我已经看到了你提到的(编码成接口,依赖注入,控制框架反转,模拟对象)的技术被滥用,并最终使事情变得更难。虽然这些技术可以得到很好的使用,但有时我会看到他们被传播,就好像它们是通向质量的唯一途径。我不同意。

从我的角度来看,为保证C代码质量++使用面向对象技术最重要的发展技术如模块化,开放 - 关闭原则,自文件,命令查询分离等

特别是,两种技术,我觉得重要的是通过合同设计(见问题What is the best way of implementing assertion checking in C++?Design by Contract in C++?)和单元测试(请参阅相关的问题123)。对于他们两个,你都有C++中的合理工具,如链接问题所示。

+0

接口依赖注入是主要的工具,使单元测试成为可能。 – 2013-05-03 16:13:00

+0

@DanBryant嗯,C++没有接口,但人们在它里面进行单元测试。 – 2013-05-03 16:15:28

+1

良好的对应点。我不假装只有一种方法来正确设计和测试。 +1提供新鲜的想法。 “合同设计”实际上是一种习惯,如果C#成功地使用了这种做法,那么在我的新环境中就会忘记。部分原因在于.NET代码合同使得它在C#中变得如此简单。我已经习惯了我们的编码对合同的接口 – Evan 2013-05-03 16:48:35

0

我可以推荐UnitTest++AMOP做测试驱动开发。两者都非常简单,并且非常强大。如果您不需要Google测试中的所有功能,这是一个不错的选择。

它可能看起来像他们,因为他们没有在一段时间更新过时,但我还没有同他们进行了单一的问题。