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

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

你知道有什么好的工具可以帮助我用 C + + 编写单元测试吗?可能是和 Junit 或者 Nunit 类似的东西?

有人能给出一些很好的建议,关于编写模块单元测试的方法,这些模块是在没有考虑单元测试的情况下编写的吗?

61583 次浏览

ObjectMentor 的 Michael Fethers 在 CppUnit 和 CppUnitLite 的开发中发挥了重要作用。

他现在推荐 CppUnitLite

我试过 CPPUnit,它不是很友好的用户界面。

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

UnitTest + + ,小而简单。

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

谷歌代码项目

CxxTest 是一个轻量级的、易于使用的、跨平台的、类似于 C + + 的 JUnit/CppUnit/xUnit 框架。

Boost 有一个包含单元测试支持的 测试库

对遗留代码应用单元测试是编写 非常理由 有效使用遗留代码的过程。迈克尔 · 费瑟斯是作者——正如在其他答案中提到的,他参与了 CppUnitCppUnitLite的创作。

alt text

内心的游戏的 Noel Llopis 是 探索 C + + 单元测试框架丛林的作者,探索 C + + 单元测试框架丛林是对各种 C + + 单元测试框架的综合评估(现在已经过时) ,也是一本关于游戏编程的书。

他使用 CppUnitLite 很长一段时间,修复了各种问题,但最终与另一个单元测试库作者合作,生成了 UnitTest + + 。我们在这里使用 UnitTest + + ,到目前为止,我非常喜欢它。它(对我来说)具有精确的权力平衡和较小的占地面积。

我使用了自己开发的解决方案 CxxTest (需要 Perl)和 ost: : test。当我在目前的工作中实现单元测试的时候,它很大程度上归结为 UnitTest + + vs ost: : test。

我非常喜欢我使用过的大多数升级库,但恕我直言,升级: : test 有点过于强硬了。我尤其不喜欢它要求你(AFAIK)使用一个升级: : 测试宏来实现测试工具的主程序。我知道它不是“纯粹的”TDD,但是有时候我们需要一种方法来在 GUI 应用程序中运行测试,例如当命令行中传入了一个特殊的测试标志,并且 ost: : 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 + + 开发,支持用户模式和内核模式单元测试。

如果您使用的是 VisualStudio2008SP1,我强烈推荐使用 MSTest 编写单元测试。然后,我使用 Google 模拟来编写模拟。与 IDE 的集成是理想的,允许并且不会带来 CPPunit 的开销,因为要添加一个测试,需要编辑三个位置。

我认为 VisualAssert在 VS 集成方面做得很好。它允许您从 VS 运行和调试测试,并且您不需要为了运行测试而创建可执行文件。

我正在使用优秀的 推进,测试库与一个鲜为人知但非常棒的 乌龟库结合使用: 一个基于升级的模拟对象库。

作为一个代码示例,假设您想要测试一个在 view接口上工作的 calculator对象(这是 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 );
}

看到在模拟对象上声明期望是多么容易和冗长了吗?显然,如果没有达到预期,测试就会失败。

我刚刚推出了自己的框架 接着。它仍在开发中,但我相信它已经超越了大多数其他框架。 不同的人有不同的标准,但我已经尝试了覆盖大多数领域没有太多的权衡。 看看我的博客链接,我的五大特色是:

  • 标题
  • 基于测试函数和方法的自动配准
  • 将标准 C + + 表达式分解为 LHS 和 RHS (因此不需要一系列断言宏)。
  • 在基于函数的夹具中支持嵌套部分
  • 使用自然语言命名测试-生成函数/方法名

它还具有 Objective-C 绑定。

CppUTest 是用于 C 和 C + + 单元测试的优秀的轻量级框架。

我目前正在寻找一个单元测试和模拟框架,可以在我们的公司长期使用的代码基地。正如你所知道的,c + + 的 单元测试框架列表很长,所以我应用了一些过滤器来将它减少到一个可以更仔细地观察的满载状态。第一个过滤条件是它必须是免费的。第二个标准是项目活动。我还在寻找嘲讽框架,因为如果你想编写单元测试,你需要一个。

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

  • GoogleTest/GoogleMock: 很多贡献者,Google 自己也在使用。这可能会在这里一段时间,并接收更新。对于我的私人代码库,我将切换到这个组合,希望跳上最快的火车。

  • BoostTest + Turtle: 不经常更新,但是测试框架是升级的一部分,所以应该维护它。另一方面,乌龟主要由一个家伙维持,但它有怨恨的活动,所以它没有死。 我使用这个组合获得了几乎所有的测试经验,因为我们在以前的工作中已经使用过升级库,而且目前我将它用于我的私有代码。

  • CppUTest: 提供测试和模拟。这个项目从2008年到2015年一直很活跃,最近也有很多活动。这个发现有点令人惊讶,因为很多活动明显减少的项目在网上搜索时出现的频率更高(比如 CppUnit 在2013年进行了最后一次更新)。我还没有深入调查,所以我不能透露任何细节。 编辑(16.12.2015) : 我最近尝试了这个框架,发现这个框架有点笨拙和“ C 风格”,特别是在使用模拟类时。此外,与其他框架相比,它似乎拥有更少的断言种类。我认为它的主要优点是可以用于纯 C 项目。译注:

  • QTest: Qt 框架附带的测试库。维护应该得到一段时间的保证,但是我把它用作一个支持库,因为测试注册在 IMO 中比在其他框架中更加笨拙。据我所知,它强制您为每个测试夹具使用一个 test-exe。但是测试辅助函数在测试 Qt-Gui 代码时可以很好地使用。它没有嘲笑。

  • 它有最近的活动,但主要是由一个家伙开发的。这个框架的优点是可选的 fixture 方法,它允许您在测试本身中编写可重用的 fixture 代码。它还允许您将测试名称设置为字符串,这在您倾向于将整个句子作为测试名称编写时是很好的。我希望这种风格可以被撕掉,放到 googleTest 中去; -)

模拟框架

模拟框架的数量比测试框架的数量要少得多,但这里是我发现的最近有活动的框架。

  • Hippomock : 从2008年到现在一直有效,但是强度很低。

  • FakeIt : 从2013年到现在一直在使用,但是或多或少是由一个家伙开发的。

结论

如果您的代码库处于长期运行状态,请在 BoostTest + TurtleGoogleTest + GoogleMock之间进行选择。我觉得这两个会有长期的维护。如果你只有一个短暂的代码基,你可以尝试 接着,它有一个很好的语法。然后,您需要另外选择一个 Mocking 框架。如果您使用 Visual Studio,您可以下载用于 BoostTest 和 GoogleTest 的测试运行器适配器,这将允许您使用集成到 VS 中的测试运行器 GUI 运行测试。

我正在使用与 类型模拟隔离器 + + 微软测试。给它一个尝试!