C++ Programmer's Cookbook

{C++ 基础} {C++ 高级} {C#界面,C++核心算法} {设计模式} {C#基础}

CPP Unit 使用


一 准备

在sourceforge.net上下载CPPUnit的源代码,地址:http://sourceforge.net/projects/cppunit ,现在最新的版本:cppunit-1.12.0.tar.gz 

二  参考

1)看CPPUnit的源代码,在你下载的目录下的src目录下,还有examples目录下的samples。
2)在源码的工程下有一个txt的帮助文件:INSTALL-WIN32.txt, 很不错,但是是英文的。    
3)更多的帮助可以查看:
// http://www.vckbase.com/document/viewdoc/?id=1762
// http://www.codeproject.com/library/Using_CPPUnit.asp
// http://cppunit.sourceforge.net/doc/1.8.0/cppunit_cookbook.html#cppunit_cookbook

三  编译(我使用vs编译)

CPPUnit: Unit test 的核心框架库
CPPUnit_dll:作用同上,区别是上面的是静态的lib,此为动态的DLL,我们使用时可以从中任选一个就可以
TestRunner:MFC扩展的DLL,负责Report的GUI浏览

TestPlugInRunner:PlugIn方式运行时,用于运行实现了CPPUnit指定接口的PlugIn DLL
DllPlugInTester:PlugIn方式运行时,在plugIn dll的post event 中使用,在对Plugin dll的编译时候检测结果。
DSPlugIn:vc6需要的addin,当某些case没有通过是,双击可以跳到指定的代码行,VS200*中不需要

四 实例 (只介绍使用宏定义来实现,宏定义使用真是太简单了,其他的原理和类的实现及关系可以参考上面的链接)

1)假设我们要测试的类:

//test data 
class SampleClass
{
public:
    
int Add(int i,int j)
    
{
        
return i+j;
    }

    
int Square(int i)
    
{
        
return i*i;
    }

}
;

2)我们需要实现相应的测试模块test case:(此类继承CppUnit::TestFixture或CPPUnit::TestCase,可以实现2个虚函数setup()和teardown(),他们在每个测试函数即case的前后自动调用)
class SampleClass_TestCase : public CppUnit::TestFixture 
{
  CPPUNIT_TEST_SUITE(SampleClass_TestCase);
      CPPUNIT_TEST(Add_Test);
      CPPUNIT_TEST(Square_Test);
  CPPUNIT_TEST_SUITE_END();

public:
    
void setUp()
    
{
        testClass 
= new SampleClass();
    }


    
void tearDown()
    
{
        delete testClass;
        testClass 
= NULL;
    }


protected:

    
void Add_Test()
    
{
        CPPUNIT_ASSERT(
6 == testClass->Add(1,4));
    }

    
    
void Square_Test()
    
{
        CPPUNIT_ASSERT(
10 == testClass->Square(3));
    }


public:
    
static std::string GetSuiteName();        

private:
    SampleClass 
*testClass;    
}
;

 std::
string SampleClass_TestCase::GetSuiteName()
{
   
return "TestSample";
}
 

3)增加上面的testcase到test suite中,当然test suite的名字是可以自己定义的。
//CPPUNIT_TEST_SUITE_REGISTRATION(SampleClassTestCase);
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(SampleClass_TestCase,SampleClass_TestCase::GetSuiteName());

4)增加上面的test suite到test runner,testrunner负责所有test suite的管理。可以使用CPPUNIT_REGISTRY_ADD( which, to ) 建立suite的树形关系。比如:CPPUNIT_REGISTRY_ADD( A, B ) ,CPPUNIT_REGISTRY_ADD( B, C )

CPPUNIT_REGISTRY_ADD_TO_DEFAULT(SampleClass_TestCase::GetSuiteName());


5)调用Testrunner,显示结果,一般有三种方式:
      第一种:GUI的方式,需要我们建立一个MFC的exe,把下面的代码加入,在我们的theapp::InitInstance()中调用下面的函数,且函数要改为返回true:     
// 1) run ui for output in mfc dialog project(.exe)

void TestMain()
{
    
     
// declare a test runner, fill it with our registered tests and run them
   CppUnit::MfcUi::TestRunner runner;
   runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest());      

   runner.run();
//show UI

}

    第二种:console的方式,需要建立一个console的exe,把下面的代码加入,在main中调用下面的函数:
// 2) run console for output in console project(.exe)

void TestMain()
{
    
// Create the event manager and test controller
    CPPUNIT_NS::TestResult controller;

    
// Add a listener that colllects test result
    CPPUNIT_NS::TestResultCollector result;
    controller.addListener( 
&result );        

    
// Add a listener that print dots as test run.
    CPPUNIT_NS::BriefTestProgressListener progress;
    controller.addListener( 
&progress );      

    
// Add the top suite to the test runner
    CPPUNIT_NS::TestRunner runner;
    
//runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() );
    runner.run( controller );

    
// Print test in a compiler compatible format.
    CPPUNIT_NS::CompilerOutputter outputter( &result, CPPUNIT_NS::stdCOut() );
    outputter.write(); 
}
  
      第三种:PlugIn的方式,建立一个DLL,加入下面的代码,且必须在此DLL中调用下面的宏之一:(需要注意的是你的dll本身有没有main函数)
      我们可以对此DLL的post -event事件中增加对DllPlugInTesterud.exe的调用来在编译的时候就得到结果, 或对编译好的DLL使用TestPlugInRunner来打 开,用GUI的方式查看结果。
// //Implements all the plug-in stuffs, WinMain
 
CPPUNIT_PLUGIN_IMPLEMENT();
// //or
// //only export function not has main function. if you have main ,use below macro
// CPPUNIT_PLUGIN_EXPORTED_FUNCTION_IMPL( CPPUNIT_NS::TestPlugInDefaultImpl );

四  更多

1)一般需要使用的头文件:
#include <cppunit/BriefTestProgressListener.h>
#include 
<cppunit/CompilerOutputter.h>
#include 
<cppunit/TestResult.h>
#include 
<cppunit/TestResultCollector.h>
#include 
<cppunit/TestRunner.h>
#include 
<cppunit/extensions/TestFactoryRegistry.h>
#include 
<cppunit/ui/mfc/TestRunner.h>
2)一般需要使用的宏定义:
//CPPUNIT_ASSERT(condition): checks condition and throws an exception if it's false. 
//CPPUNIT_ASSERT_MESSAGE(message, condition): checks condition and throws an exception and showing 
//specified message 
if it is false
//CPPUNIT_ASSERT_EQUAL(expected,current): checks if expected is the same as current, and raises exception 
//showing expected and current values. 
//CPPUNIT_ASSERT_EQUAL_MESSAGE(message,expected,current): checks if expected is the same as actual, and 
//raises exception showing expected and current values, and specified message. 
//CPPUNIT_ASSERT_DOUBLES_EQUAL(expected,current,delta): checks if expected and current difference is 
//smaller than delta. If it fails, expected and current values are shown. 
3)如果我们对想对我们的整个工程下的函数进行单元测试,且想使测试代码和我们的正式代码分离,这时我们可以为我们的测试代码建立一个单独的dll(使用plugin)或exe(输出到GUI或console),在此测试工程中加入我们正式的代码,但是不对我们正式的代码进行拷贝,但是如果我们的project的静态的lib,则我们可以直接调用不需要把代码再加入测试模块中。

posted on 2007-06-25 22:50 梦在天涯 阅读(5562) 评论(0)  编辑 收藏 引用 所属分类: CPlusPlus


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


公告

EMail:itech001#126.com

导航

统计

  • 随笔 - 461
  • 文章 - 4
  • 评论 - 746
  • 引用 - 0

常用链接

随笔分类

随笔档案

收藏夹

Blogs

c#(csharp)

C++(cpp)

Enlish

Forums(bbs)

My self

Often go

Useful Webs

Xml/Uml/html

搜索

  •  

积分与排名

  • 积分 - 1796886
  • 排名 - 5

最新评论

阅读排行榜