C ++中的单元和集成测试

时间:2009-09-23 23:03:05

标签: c++ unit-testing testing

我将用C ++为学校项目编写一个非常大的应用程序。到目前为止,我已经习惯使用JUnit和RSpec在Java和Ruby中使用TDD。

但就我的经验而言,我从未见过任何测试套件的C / C ++项目。

您建议在C ++中使用哪个库进行测试?
C ++有什么好的模拟/存根框架吗?

实际上我正在使用NetBeans IDE,似乎没有任何支持进行测试 您会在C ++中为TDD推荐什么工具?

TDD甚至可以使用C ++吗?编译时似乎是一个很大的缺点。

10 个答案:

答案 0 :(得分:7)

Boost Test Library为您提供单元测试等。

答案 1 :(得分:5)

C ++有很多单元测试框架。我最有经验的是CppUnit和CxxTest。我更喜欢CxxTest,因为我发现更容易不必明确注册我的测试用例,因为你必须使用CppUnit。有一个用于CxxTest的eclipse插件,但我不知道是否有一个用于NetBeans的插件。编写时间不应该是编写良好的C ++的问题,并且绝对不是跳过单元测试/ tdd的理由。

对于验收测试我使用过精确度。这是一个基于java的工具,但在C ++环境中使用并不困难。

答案 2 :(得分:5)

我们使用Google Test Framework。我们不会在开发人员机器上的每个编译上运行测试。这是构建服务器的工作。

答案 3 :(得分:5)

比较CppTest和CppUnit我会选择CppTest。 CppTest具有较少的隐藏框架,IMO更易于理解和实现。我个人希望看到入口点。我还包括了Boost Unit Testing Framework。它不是基于xUnit的。我不是粉丝,但如果您已经在使用Boost Library,那么合并将非常好。


CppTest与CppUnit

  

易于创建单元测试和测试   套件即可。 CppUnit和CppTest都创建   类方法的单元测试,用   类本身来自某些   工具提供的测试类。语法   对于CppTest来说稍微简单一点,   但是,随着测试注册   发生在课堂内   构造函数。在CppUnit的情况下,   额外的宏   CPPUNIT_TEST_SUITE和   需要CPPUNIT_TEST_SUITE_ENDS。

     

运行测试。 CppTest简单   在测试中调用run方法   套件,而CppUnit使用单独的   运行方法为的TestRunner类   被调用以运行测试。

     

扩展测试层次结构。在   在CppTest的情况下,它总是如此   可以延长以前的测试   套件通过创建一个新的类   继承旧的。新的   class将定义一些额外的   添加到单元测试的函数   池。您只需调用run方法即可   在新类类型的对象上。   相比之下,CppUnit需要这样做   你使用宏   CPPUNIT_TEST_SUB_SUITE以及   类继承实现相同   影响。

     

生成格式化输出。都   CppTest和CppUnit都有这种能力   自定义输出。然而,   虽然CppTest有用,   预定义的HTML输出格式化程序   CppUnit没有。但是,CppUnit   专门支持XML格式。   两者都支持文本和编译器样式   格式。

     

创建测试夹具。要使用测试   夹具,CppUnit要求   测试类来源于   CppUnit的::的TestFixture。你必须提供   设置和定义   拆除程序。如果是   CppTest,你需要提供   仅适用于设置和的定义   拆除程序。这绝对是   一个更好的解决方案,因为它保持   客户端代码简单。 •预定义   实用宏支持。两者都是CppTest   和CppUnit有一套可比的   用于断言的宏,处理浮点数,   等等。

     

标头文件。 CppTest要求   你包括一个头文件,   而CppUnit客户端代码必须包含   多个标头,如HelperMacros.h   和TextTestRunner.h,取决于   使用的功能。

http://www.ibm.com/developerworks/aix/library/au-ctools3_ccptest/index.html?ca=drs-


<强> CPPTEST

#include “cppTest.h”

class myTestWithFixtures : public Test::Suite { 
  void function1_to_test_some_code( );
  void function2_to_test_some_code( );

  public: 
  myTestWithFixtures ( ) { 
      TEST_ADD (function1_to_test_some_code) {...}; 
      TEST_ADD (function2_to_test_some_code) {...}; 
  } 

  protected: 
    virtual void setup( ) { ... };
    virtual void tear_down( ) { ... };
}; 

int main ( ) 
{ 
  myTestWithFixtures tests; 
  Test::TextOutput output(Test::TextOutput::Verbose);
  return tests.run(output);
} 

http://www.ibm.com/developerworks/aix/library/au-ctools3_ccptest/index.html?ca=drs-


<强>的CppUnit

#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TextTestRunner.h>
#include <cppunit/extensions/HelperMacros.h>

class mystringTest : public CppUnit::TestFixture {
public:
  void setUp() { ... };
  void tearDown() { ... };

  void function1_to_test_some_code() { ... };
  void function2_to_test_some_code() { ... };

  CPPUNIT_TEST_SUITE( mystringTest );
  CPPUNIT_TEST( function1_to_test_some_code );
  CPPUNIT_TEST( function2_to_test_some_code );
  CPPUNIT_TEST_SUITE_END();
};
CPPUNIT_TEST_SUITE_REGISTRATION( mystringTest );

没有宏

int main ()
{
  CppUnit::TestSuite* suite = new CppUnit::TestSuite("mystringTest");
  suite->addTest(new CppUnit::TestCaller<mystringTest>("checkLength",
                &mystringTest::checkLength));
  suite->addTest(new CppUnit::TestCaller<mystringTest>("checkValue",
                &mystringTest::checkLength));

  // client code follows next 
  CppUnit::TextTestRunner runner;
  runner.addTest(suite);

  runner.run();
  return 0;
}

http://www.ibm.com/developerworks/aix/library/au-ctools2_cppunit/


提升单元测试框架

#include <boost/test/unit_test.hpp>

using namespace std;

struct CMyFooTestFixture
{
    CMyFooTestFixture() { ... } //SetUp
    ~CMyFooTestFixture() { ... } //TearDown

    void function1_to_test_some_code(CMyFoo& foo) { ... };
    void function2_to_test_some_code(CMyFoo& foo) { ... };
}

BOOST_FIXTURE_TEST_SUITE(MyFooTest, CMyFooTestFixture);

BOOST_AUTO_TEST_CASE(function1_to_test_some_code)
{
    CMyFoo foo;
    function1_to_test_some_code(foo);
}

BOOST_AUTO_TEST_CASE(function1_to_test_some_code2)
{
    CMyFoo foo;
    function1_to_test_some_code(foo);
}

BOOST_AUTO_TEST_SUITE_END();

http://www.beroux.com/english/articles/boost_unit_testing/

答案 4 :(得分:3)

对于集成测试,我是否可以建议FIT(集成测试框架)的C ++实现 - http://fit.c2.com又名CEEFIT(http://ceefit.woldrich.com/?page=Home)(在撰写本文时,ceefit网站已关闭。希望很快就会回来)。我个人使用CEEFIT在遗留的C ++代码库上运行集成测试,这些代码库与计算机辅助设计平台API(SolidWorks,如果您了解它)相互作用。我很幸运,CEEFIT是开源的,因为我必须扩展它来做自定义的事情,比如读取多个表作为输入(默认行为是读取测试类的单个表)。在与CEEFIT合作至少一年后,我相信我可以使用此工具在大多数系统上运行集成测试。

无耻的插件 - 我的一些博客文章叙述了我对CEEFIT下载的体验 http://ossandcad.blogspot.com/2009/07/swx-batch-mode-integrated-tests-with.html http://ossandcad.blogspot.com/2009/02/writing-ceefit-class-like-regular-c.html

但是有一些关于CEEFIT的注意事项 - 通过表格式提供输入并不总是可行的(不是CEEFIT的错,这是由FIT设计的,CEEFIT只是简单地实现)。源代码多年来一直没有更新,如果内存服务正常(因为网站已关闭),自2005年以来(但由于它的开源,这对我的工作没有造成很多问题)。

答案 5 :(得分:2)

如果您曾经使用过JUnit和jMock,我建议您:

Googlemock ,与 Googletest 无缝合作。

对于TDD,我自己使用

我自己编写的一些脚本。所有这些都运作良好。

答案 6 :(得分:2)

我们正在努力使单元测试和TDD对C ++可行。我们扩展Eclipse CDT来实现这一目标。目前您可以尝试:

http://cute-test.com - 我们使用Eclipse CDT插件的单元测试框架

我的一位硕士生正在实施“Mockator”模拟对象基础设施,该基础设施通过引入模板参数而不是通过继承的义务(例如使用google mock)通过依赖注入来工作。这应该可以在今年夏天晚些时候通过我们的CUTE插件获得。

另一个学生团队已经实现了对Eclipse CDT的TDD支持,它将再次集成在我们可爱的插件中(但也可以在没有CUTE框架的情况下工作)。

所有这些都将免费提供。

答案 7 :(得分:0)

无耻插件:查看cfixVisual Assert

答案 8 :(得分:0)

unittest ++

答案 9 :(得分:0)

当您使用JUnit时,您可以轻松使用CPPUnit