C ++代码的单元测试-工具和方法论


134

我正在开发一个已经开发了几年的大型c ++系统。为了提高现有代码的质量,我们参与了一个大型的长期重构项目。

您知道一个好的工具可以帮助我用C ++编写单元测试吗?也许类似于Junit或Nunit?

谁能在编写没有单元测试的模块的单元测试的方法上给出任何好的建议?


Answers:


83

将单元测试应用于遗留代码是编写有效与遗留代码一起工作原因 。迈克尔·费瑟斯(Michael Feathers)是作者-如其他答案所述,他参与了CppUnitCppUnitLite的创建。

替代文字


4
添加了缩略图-已投票。这本书比任何工具都有帮助。
Gishu

2
我认为CPPUnit可以简化编写测试的过程。我们使用CPPUnit,但我不满意。我需要为每个测试更新两个文件,并且我认为测试的编写应像这样简单:'TEST(“ testname”){ASSERT(1 == 1);}'另一方面,这本书是是每个人的
必需品

9
从什么时候起c ++成为遗产?
尼尔斯2010年

9
并不是说C ++是遗留的-如果我没记错的话,那本书将遗留项目定义为一个没有或只有很少的单元测试的项目。这样的项目确实倾向于/ hard /编写单元测试,因为测试驱动的开发从未影响过代码库,因此编写它们很简单。
Arafangion 2010年

7
@Nils:正如本书的一位亚马逊评论家提到的那样,“传统代码是没有单元测试的代码”,这正是这个问题的实质。
大卫·约翰斯通

40

Google最近发布了他们自己的用于单元测试C ++应用程序的库,称为Google Test。

在Google Code上进行项目


1
是否可以在VC ++中使用它
yesraaj

似乎还可以,尤其是它们必须向每个断言添加描述的方式。不利的一面是,我个人更喜欢使用单元测试类,而不是真正看起来并不像类的宏。
2010年

3
另一个好点是嘲讽的可能性:code.google.com/p/googlemock
Philipp 2010年

我发现这比CPPUNIT更好,后者需要大量的宏和魔术文件才能使测试正常工作
paulm

30

在几个可用套件之间进行出色的比较。该文章的作者后来开发了UnitTest ++

我特别喜欢它(除了它可以很好地处理异常等事实),围绕测试用例和测试装置定义的“管理”数量非常有限。


2
这不是我们的根本谬误吗?他对可用的项目有很好的洞察力-但他没有改进它们,而是开始自己的项目。
peterchen

@peterchen:是的;但是然后UnitTest ++是如此的小巧轻巧,以至于作为一个独立的项目具有价值-易于安装和运行。
TimStaley,2012年


21

从内在游戏》的 Noel Llopis 是《探索C ++单元测试框架丛林》的作者一书的作者,该书对各种C ++单元测试框架进行了全面(但已注明日期)评估,以及一本有关游戏编程的书。

他使用CppUnitLite已有相当长的一段时间,修复了各种问题,但最终与另一位单元测试库作者合力,并制作了UnitTest ++。我们在这里使用UnitTest ++,到目前为止,我非常喜欢它。(对我而言)它具有很小的占位面积,功率的精确平衡。

我使用了本地开发的解决方案,CxxTest(需要Perl)和boost :: test。当我在目前的工作中执行单元测试时,它几乎可以归结为UnitTest ++ vs boost :: test。

我真的很喜欢我使用过的大多数boost库,但是恕我直言,boost :: test有点笨拙。我特别不喜欢它要求您(AFAIK)使用boost :: test宏来实现测试工具的主程序。我知道它不是“纯” TDD,但是有时我们需要一种从GUI应用程序运行测试的方法,例如,当在命令行中传递特殊测试标志时,而boost :: test无法支持这种类型场景。

UnitTest ++是我(有限的)经验中遇到的最简单的设置和使用测试框架。


17

我将优秀的Boost.Test库与鲜为人知但令人敬畏的Turtle库结合使用:基于boost的模拟对象库。

正如代码示例胜于语言一样,请想象您想测试一个calculatorview接口上工作的对象(这是Turtle的入门示例):

// declares a 'mock_view' class implementing 'view'
MOCK_BASE_CLASS( mock_view, view )
{
    // implements the 'display' method from 'view' (taking 1 argument)
    MOCK_METHOD( display, 1 )                   
};

BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
{
    mock_view v;
    calculator c( v );

    // expects the 'display' method to be called once with a parameter value equal to 0
    MOCK_EXPECT( v, display ).once().with( 0 ); 

    c.add( 0, 0 );
}

看看在模拟对象上声明期望有多么容易和冗长?显然,如果未达到期望,则测试将失败。


14

我刚刚推出了自己的框架CATCH。它仍在开发中,但我相信它已经超越了大多数其他框架。不同的人有不同的标准,但我试图在没有太多取舍的情况下涵盖大多数领域。看看我的品酒师链接博客条目。我的五个主要功能是:

  • 仅标题
  • 自动注册基于功能和方法的测试
  • 将标准C ++表达式分解为LHS和RHS(因此您不需要一整套的断言宏)。
  • 支持基于功能的灯具中的嵌套部分
  • 使用自然语言进行名称测试-生成函数/方法名称

它还具有Objective-C绑定。


4
doctest是我对Catch的重新实现,重点是编译速度- 请查看FAQ以了解它们的不同之处
onqtam,2013年




6

我目前正在寻找可以在我们公司中使用很长一段时间的代码库的单元测试和模拟框架。如您所知,单元测试框架列表用于c ++很长,因此我应用了一些过滤器以将其减少到可以更仔细地查看。第一个过滤条件是必须免费。第二个标准是项目活动。我还寻找了模拟框架,因为如果要编写单元测试,则需要一个框架。

我提出了以下列表(大约),按活动排序,最高的活动在顶部:

  • GoogleTest / GoogleMock:许多贡献者,由Google本身使用。它可能会在这里待一段时间并接收更新。对于我的私人代码库,我将切换到此组合,以期跳上最快的火车。

  • BoostTest + Turtle:不会经常更新,但是测试框架是boost的一部分,因此应予以维护。另一方面,乌龟主要由一个人维护,但它有反感的活动,因此没有死。我几乎通过这种组合获得了所有的测试经验,因为我们在上一份工作中已经使用了boost库,并且目前将其用于私有代码。

  • CppUTest:提供测试和模拟。该项目从2008年到2015年一直活跃,并且最近有很多活动。这个发现有点意外,因为在网络上搜索时,很多活动活动明显减少的项目(例如CppUnit的最新更新于2013年)出现的频率更高。我没有对此进行深入研究,所以我无法透露任何细节。 编辑(16.12.2015):我最近尝试了一下,发现此框架有点笨拙和“ C 风格 ”,尤其是在使用模拟类时。而且它似乎比其他框架具有更少的断言。我认为它的主要优点是可以与纯C项目一起使用。

  • QTest: Qt框架附带的测试库。应该保证维护一段时间,但是我将其用作支持库,因为与其他框架相比,IMO的测试注册更加笨拙。据我了解,它迫使您每个测试治具只有一个test-exe。但是,在测试Qt-Gui代码时,测试助手功能可以很好地使用。它没有模拟。

  • 抓住:它最近有活动,但主要由一个人开发。关于此框架的好处是,备用的夹具方法使您可以在测试本身中编写可重用的夹具代码。它还使您可以将测试名称设置为字符串,这在您倾向于将整个句子都写为测试名称时非常有用。我希望这种样式会被撕掉并放入googleTest ;-)

模拟框架

模拟框架的数量比测试框架的数量小得多,但以下是我发现最近有活动的框架。

  • 河马(Hippomock):从2008年起开始活跃,但力度不大。

  • FakeIt:从2013年unitl开始活跃,但或多或​​少由一个人开发。

结论

如果您的代码库可以长期使用,请在BoostTest + TurtleGoogleTest + GoogleMock之间进行选择。我认为这两个将长期维护。如果您只有短暂的代码库,可以尝试使用Catch,它的语法很好。然后,您将需要另外选择一个模拟框架。如果使用Visual Studio,则可以下载BoostTest和GoogleTest的测试运行程序适配器,这将允许您使用集成到VS中的测试运行程序GUI运行测试。


3

参见答案密切相关的问题:“选择一个C ++单元测试工具/框架”,在这里


3

还有一个TUT,Template-Unit-Test,一个基于模板的框架。它的语法很尴尬(有人称其为滥用模板),但是它的主要优点是它们全部包含在一个头文件中

您将在此处找到用TUT编写的单元测试示例


2
我建立了一个仅标头的库,该库提供了包装TUT的sure函数和测试清点代码的宏,以简化它并在失败时提供文件和行号信息。这是一篇文章链接,其中包含输出和代码差异的示例,以及到github上项目的链接:codecrafter.wordpress.com/2012/12/19/tutadapter1
Josh Heitzman 2012年

2

我已经尝试过CPPunit,它不是非常用户友好。

我知道的唯一替代方法是使用C ++。NET包装C ++类,并使用一种.NET单元测试框架(NUnit,MBUnit等)编写单元测试。





1

看一下cfix(http://www.cfix-testing.org),它专门用于Windows C / C ++开发,并且支持用户模式和内核模式单元测试。


感谢分享。我最近开始使用cfix进行测试。我一直在寻找一种方法来查看通过和失败的测试用例的调用堆栈。cfix中有办法实现这一目标吗?
tryToLearn

1

如果您使用的是Visual Studio 2008 SP1,则强烈建议使用MSTest编写单元测试。然后,我使用Google模拟来编写模拟。与IDE的集成是理想的选择,并且允许并且不承担CPPunit在编辑三个位置以添加一个测试方面的开销。




By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.