cppunit是C++的unit test工具,CppUnit测试框架的源代码可以到 http://sourceforge.net/projects/cppunit/ 上下载。
1. cppunit的编译
cppunit的编译很简单,直接打开编译就可以啦,好像只有addone会编译失败,它只是用于vc6!cppunit提供了debug、debug static、debug unicode等等版本,按照自己的需求选择就可以啦。
2. 编写测试代码
-
TestCase
class mytest : public CppUnit::TestCase {
..
void runTest() {
CPPUNIT_ASSERT(myFunc() == 0);
}
}
编译执行即可,记得加上.h文件和lib文件。
-
Fixture
首先自己实现一个继承自Fixture的类,让后override他的两个成员函数, setUp和tearDown, 这两个函数用来自动分配和释放资源。之后你就可以自己写一个测试用例的,随便起个什么名字。
class myfixture : public CppUnit::Fixture {
...
setUp() {
alloc resouce.
}
tearDown() {
release resource...
}
..
void textMyFunction1() { test code... }
void textMyFunction2() { test code... }
}.
-
TestCaller
写完了测试代码,还要让他运行。 自己写代码加到main函数里.
CppUnit::TestCaller<myfixture> test( "textMyFunction1",
&myfixture ::textMyFunction1);
CppUnit::TestResult result;
test.run( &result );
-
TestSuite
CppUnit::TestSuite suite;
CppUnit::TestResult result;
suite.addTest( new CppUnit::TestCaller(
"testMyFunction1",
&myfixture::testMyFunction1) );
suite.addTest( new CppUnit::TestCaller(
"testMyFunction2",
&myfixture::testMyFunction2) );
suite.run( &result );
-
TestRunner
在你编写完一个TestSuit之后,你就可以运行它了。TestRunner就提供了观察测试结果的工具,你学要做的就是将运行TestSuite代码加入到一个类的静态函数suite当中,例如:
class myfixture {
public:
....
static CppUnit::Test *suite() {
CppUnit::TestSuite *suite = new CppUnit::TestSuite("mytestsuite");
suite->addTest( new CppUnit::TestCaller(
"testMyFunction1",
&myfixture::testMyFunction1) );
suite->addTest( new CppUnit::TestCaller(
"testMyFunction2",
&myfixture::testMyFunction2) );
return suite;
}
};
最后在main函数中加入
int main( int argc, char **argv) {
CppUnit::TextUi::TestRunner runner;
runner.addTest( myfixture::suite() );
runner.addTest( ....::suite() );
runner.run();
return 0;
}
3.CppUnit帮助宏
如果像上面那样写测试代码,真的会累死人啊。还好CppUnit提供了一组宏,它可以减少代码量嘔!!使用这些宏我可以像这样编写一个测试类 #include <cppunits/extensions/helperMacros>
class MyFixture : public CppUnit::TextFixture {
CPPUNIT_TEST_SUITE(MyFixture); // 告诉类的名称
CPPUNIT_TEST(MyTestFunction1); // 告诉测试函数的名称
CPPUNIT_TEST(MyTestFunction2);
CPPUNIT_TEST_EXCEPTION(MyTestFun3, Exception);
CPPUNIT_TEST_SUITE_END();
}
注意到CPPUNIT_TEST_EXCEPTION宏了吗,与CPPUNIT_TEST不同,它提供了捕捉异常的功能,如果MyTestFun3在执行结束后没有抛出Exception异常,则测试用例失败。
在编写完测试代码之后,我们仍然需要写我们的main函数,但是这次我们不需要一个一个的将Fixture加入到TestRunner当中了。只需要对每一个测试类进行注册:
CPPUNIT_TEST_SUITE_REGISTRATION(MyFixture)
main函数编程这样
int main( int argc, char **argv) {
CppUnit::TextUi::TestRunner runner
CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry();
runner.addTest( registry.makeTest() );
runner.run();
return 0;
}
所有的main函数都是这个样子,不用改了, 做个宏叫做CPPUNIT_RUN_ALLTEST()多好啊, 唉~~。
当然还要包含头文件
#include <cppunits/extensions/helperMacros>
#include
#include
4.CppUnit常用测试宏
- 断言
CPPUNIT_ASSERT_EQUAL()
CPPUNIT_ASSERT_DOUBLES_EQUAL()
CPPUNIT_FAIL("Failed reasion") //
我们还可以使用一些带有消息的断言, 如
CPPUINT_ASSERT_MESSAGE(msg, condition)
这些宏的定义可以在http://cppunit.sourceforge.net/doc/1.11.6/group___assertions.html#ga2上找到
5. 例子
在了解了CPPUNIT之后,做了一个基本的例子,只要修修补补就可以直接用啦
首先包含以下头文件
#include
#include
#include
#include
#include
#include
#include
#include
还要包含以下库,如果是在vc下,可以这样
#ifdef _DEBUG
# pragma comment(lib, "cppunitd.lib")
# pragma comment(lib, "testrunnerd.lib")
#else
# pragma comment(lib, "TestRunner.lib")
# pragma comment(lib, "cppunit.lib")
#endif
添加一个测试类
class RuleCheckerTest : public TestFixture {
public:
CPPUNIT_TEST_SUITE(RuleCheckerTest);
CPPUNIT_TEST(TESTCheckIP);
CPPUNIT_TEST(TESTUnCheck);
CPPUNIT_TEST(TESTremoveDNS);
CPPUNIT_TEST_SUITE_END();
public:
virtual void setUp();
virtual void tearDown();
protected:
void TESTCheckIP();
void TESTUnCheck();
void TESTremoveDNS();
IRulesChecker * pRulesChecker_;
IRulesSettings * pRulesSetting_;
};
注册它
CPPUNIT_TEST_SUITE_REGISTRATION(RuleCheckerTest);
主函数:
int _tmain(int argc, _TCHAR* argv[]) {
// 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();
return result.wasSuccessful() ? 0 : 1;
}
这样就这可以了,只要根据自己的需要进行修补就OK啦