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

时间:2020-03-06 14:20:42  来源:igfitidea点击:

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

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

任何人都可以就编写单元测试而没有考虑单元测试的方法给出一些好的建议吗?

解决方案

CppUnit是方法。请参阅下面的链接:

http://cppunit.sourceforge.net/cppunit-wiki

http://en.wikipedia.org/wiki/CppUnit

ObjectMentor的Michael Feathers有助于CppUnit和CppUnitLite的开发。

他现在推荐CppUnitLite

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

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

UnitTest ++,小巧而简单。

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

在Google Code上进行项目

CxxTest是一个轻便,易于使用且跨平台的C ++类JUnit / CppUnit / xUnit框架。

Boost具有测试库,其中包含对单元测试的支持。可能值得一试。

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

替代文字http://ecx.images-amazon.com/images/I/51RCXGPXQ8L.SL160_AA115.jpg

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

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

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

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

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

查看果糖:http://sourceforge.net/projects/fructose/

这是一个非常简单的框架,仅包含头文件,因此易于移植。

另请参见与"选择c ++单元测试工具/框架"密切相关的问题的答案。

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

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

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

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

看看CUnitWin32. 它是为MS Visual C编写的。它包含一个示例。

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

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

我认为VisualAssert在VS集成方面做得很好。它使我们可以从VS运行和调试测试,而无需创建可执行文件即可运行测试。

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

正如代码示例胜于语言一样,假设我们想测试一个在"视图"界面上工作的"计算器"对象(这是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 );
}

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

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

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

它还具有Objective-C绑定。