【问题标题】:Unit testing for C++ code - Tools and methodology [closed]C ++代码的单元测试-工具和方法[关闭]
【发布时间】:2010-09-10 14:54:26
【问题描述】:

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

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

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

【问题讨论】:

标签: c++ unit-testing refactoring


【解决方案1】:

将单元测试应用于遗留代码是编写Working Effectively with Legacy Code非常原因。 Michael Feathers 是作者 - 正如其他答案中提到的,他参与了 CppUnitCppUnitLite 的创建。

【讨论】:

  • 添加了缩略图 - 投了赞成票。这本书比任何工具都更有帮助。
  • 我认为 CPPUnit 可以让编写测试变得更简单。我们使用 CPPUnit,但我并不满意。我需要为每个测试更新两个文件,在我看来,测试应该像这样简单地编写:'TEST("testname") {ASSERT(1==1);}' 另一方面的书是对每个人来说都是必须的,不仅是那些使用遗留代码的人,还有那些创造它的人;)
  • c++ 什么时候遗留下来的?!
  • 这并不是说 C++ 是遗留的——如果我没记错的话,那本书将遗留项目定义为没有单元测试或单元测试很少的项目。这样的项目确实倾向于/hard/编写单元测试,因为测试驱动开发从未影响代码库,因此编写它们是微不足道的。
  • @Nils:正如该书的一位亚马逊评论者所提到的,“遗留代码是没有单元测试的代码”,这正是这个问题的意义所在。
【解决方案2】:

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

Project on Google Code

【讨论】:

  • VC++可以用这个吗
  • 看起来还不错,尤其是他们必须为每个断言添加描述的方式。不利的一面是,我个人更喜欢有一个单元测试类,而不是看起来不像类的宏。
  • 另一个不错的点是模拟的可能性:code.google.com/p/googlemock
  • 我发现这比 CPPUNIT 要好得多,它需要大量的宏和魔法文件才能使测试工作
【解决方案3】:

在几个可用套件之间查看出色的comparison。那篇文章的作者后来开发了UnitTest++

我特别喜欢它的一点(除了它可以很好地处理异常等)是围绕测试用例和测试夹具定义的“管理”数量非常有限。

【讨论】:

  • 这不是我们的基本谬误吗?他对可用项目有很好的洞察力 - 但他没有改进它们,而是开始了自己的项目。
  • @peterchen:是的;但是 UnitTest++ 是如此的小而轻,以至于它作为一个单独的项目很有价值——它很容易启动和运行。
【解决方案4】:

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

【讨论】:

  • 我可以推荐这个优秀的工具包。
  • 是的,提升是要走的路。没有开销,只需测试即可!当 boost 来救我时,我实际上是在绝望地开发自己的框架。谢谢你的提升(一切!)
  • 你可以看看我写的一篇文章介绍 Boost Unit Testing beroux.com/english/articles/boost_unit_testing
【解决方案5】:
Games From Within 的 Noel Llopis 是 Exploring the C++ Unit Testing Framework Jungle 的作者,这是对各种 C++ 单元测试框架的全面(但现已过时)评估,也是一本关于游戏编程的书。

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

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

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

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

【讨论】:

    【解决方案6】:

    我将出色的 Boost.Test 库与一个鲜为人知但非常棒的 Turtle 库结合使用:一个基于 boost 的模拟对象库。

    代码示例胜于雄辩,假设您想测试一个在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 );
    }
    

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

    【讨论】:

      【解决方案7】:

      我刚刚推出了自己的框架CATCH。它仍在开发中,但我相信它已经超越了大多数其他框架。 不同的人有不同的标准,但我试图在没有太多权衡的情况下涵盖大部分内容。 请查看我的链接博客条目以供品酒师使用。我的前五个功能是:

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

      它还具有 Objective-C 绑定。

      【讨论】:

      • doctest 是我对 Catch 的重新实现,非常注重编译速度 - 查看 FAQ 以了解它们有何不同
      【解决方案8】:

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

      【讨论】:

        【解决方案9】:

        【讨论】:

          【解决方案10】:

          UnitTest++,小而简单。

          【讨论】:

            【解决方案11】:

            我目前正在寻找可以在我们公司用于长期代码库的单元测试和模拟框架。如您所知,c++ 的list of unit testing frameworks 很长,因此我应用了一些过滤器将其缩小到可以更仔细查看的手感。第一个过滤标准是它必须是免费的。第二个标准是项目活动。我还寻找了模拟框架,因为如果你想编写单元测试,你需要一个。

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

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

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

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

            • QTest: Qt 框架附带的测试库。维护应该保证一段时间,但我将它用作支持库,因为测试注册在 IMO 中比在其他框架中更笨拙。据我了解,它迫使您每个测试夹具都有一个测试exe。但是测试辅助函数在测试 Qt-Gui 代码时会很有用。它没有模拟。

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

            模拟框架

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

            • Hippomock:从 2008 年至今活跃,但强度较低。​​

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

            结论

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

            【讨论】:

              【解决方案12】:

              另请参阅密切相关的问题“选择 c++ 单元测试工具/框架”的答案here

              【讨论】:

                【解决方案13】:

                还有TUT,Template-Unit-Test,一个基于模板的框架。它的语法很笨拙(有些人称之为模板滥用),但它的主要优点是它全部包含在single header file 中。

                您会在此处找到example of unit-test written with TUT

                【讨论】:

                • 我建立了一个只有头文件的库,提供了包装 TUT 的确保函数和测试解密代码的宏,以简化它并在失败时提供文件和行号信息。这是一个帖子的链接,其中包含输出和代码差异的示例,以及 github 上的项目链接:codecrafter.wordpress.com/2012/12/19/tutadapter1
                【解决方案14】:

                我尝试过 CPPunit,但它对用户不太友好。

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

                【讨论】:

                  【解决方案15】:

                  CppUTest 是一个出色的轻量级 C 和 C++ 单元测试框架。

                  【讨论】:

                    【解决方案16】:

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

                    他现在推荐CppUnitLite

                    【讨论】:

                      【解决方案17】:

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

                      【讨论】:

                        【解决方案18】:

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

                        【讨论】:

                        • 感谢分享。我最近开始使用 cfix 进行测试。我正在寻找一种在通过和失败的测试用例的情况下查看调用堆栈的方法。 cfix 有没有办法做到这一点?
                        【解决方案19】:

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

                        【讨论】:

                          【解决方案20】:

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

                          【讨论】:

                            【解决方案21】:

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

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

                            【讨论】:

                              【解决方案22】:

                              我正在使用带有Typemock Isolator++ 的 MS 测试。试试看!

                              【讨论】:

                                猜你喜欢
                                • 2010-09-09
                                • 2011-02-07
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 2016-02-23
                                • 1970-01-01
                                • 2013-01-05
                                相关资源
                                最近更新 更多