CppUnit定义了几个基础类以及几个继承它们的子类。
基础类主要是定义了一些virtual函数,规定一些行为;用户主要继承使用如TestCase这样的类来完成测试用例。
TestFixture
定义了setUp()和tearDown()两个virtual函数,用来给测试中用到的对象实例做初始化和清理。
Test/TestLeaf(单个test)/TestComposite(多个test)
定义了一系列的接口,规定了测试的类型,继承给TestCase和TestSuite等类
TestCase
单个test的类,继承了TestLeaf和TestFixture。一般使用者都写继承它的子类做测试,在setUp()函数里面初始化要使用的对象实例,在tearDown()函数进行销毁。
TestSuite
多个test的类,继承了TestComposite。一般会在TestCase/TestFixture的子类里面定义一个Test *suite()的函数,里面添加了多个TestCase/TestFixture的测试方法。
TestRunner
运行测试并收集测试结果的类。可以添加Test类型的实例(包括TestCase/TestSuite)
#include <cppunit/TestCase.h> #include <cppunit/TextTestRunner.h> #include <cppunit/TestResult.h> #include <iostream> using namespace std; class MyTest: public CppUnit::TestCase { public: MyTest(string name): CppUnit::TestCase(name){} void runTest() { CPPUNIT_ASSERT( 1 == 2 ); cout << "runTest()" << endl; } }; int main() { MyTest *t = new MyTest("MyTest"); CppUnit::TestResult result; CppUnit::TextTestRunner r; r.addTest(t); r.run("", true); return 0; }其中,runTest()函数是TestCase必须重载的,在测试运行的时候会被调用。 CPPUNIT_ASSERT等一系列宏定义在TestAssert.h里面,用作判断测试是否通过。TextTestRunner继承了TestRunner类,用作运行测试并收集测试结果的实例。
$ g++ MyTest.cpp -o MyTest -lcppunit -ldl如果报错,一般是动态链接库或者include路径没有识别,一般make cppunit以后,头文件放在/usr/local/include/cppunit/下,库文件在/usr/local/lib/下。在/etc/ld.so.conf下添加/usr/local/lib并运行ldconfig就可以了。
.F !!!FAILURES!!! Test Results: Run: 1 Failures: 1 Errors: 0 1) test: MyTest (F) line: 33 MyTest.cpp assertion failed - Expression: 1 == 2 <RETURN> to continue因为1==2这个断言不成立,所以测试不通过,cppunit会报告测试的结果和错误的位置。
#include <cppunit/TextTestRunner.h> #include <cppunit/TestResult.h> #include <cppunit/TestSuite.h> #include <cppunit/TestCaller.h> #include <iostream> using namespace std; class MyTest: public CppUnit::TestCase { public: void setUp(){} void tearDown(){} void test1() { CPPUNIT_ASSERT( 1 == 1); } void test2() { CPPUNIT_ASSERT( 2 == 2); } //other tests //... static CppUnit::Test *suite() { CppUnit::TestSuite *suiteOfTests = new CppUnit::TestSuite("ThisIsATestSuite"); suiteOfTests->addTest(new CppUnit::TestCaller<MyTest>("test1", &MyTest::test1)); suiteOfTests->addTest(new CppUnit::TestCaller<MyTest>("test2", &MyTest::test2)); return suiteOfTests; } }; int main() { CppUnit::TestResult result; CppUnit::TextTestRunner r; r.addTest(MyTest::suite()); r.run("", true); return 0; }在这里,我们定义了多个测试函数,并通过suite()函数添加到一个TestSuite类里面,最后通过TextTestRunner的addTest()添加。注意,suite()函数返回的是一个Test对象的指针。
#include <cppunit/TextTestRunner.h> #include <cppunit/TestResult.h> #include <cppunit/TestSuite.h> #include <cppunit/TestCaller.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> #include <iostream> using namespace std; class MyTest: public CppUnit::TestCase { public: void setUp(){} void tearDown(){} void test1() { CPPUNIT_ASSERT( 1 == 1); } void test2() { CPPUNIT_ASSERT( 2 == 2); } //other tests //... /* static CppUnit::Test *suite() { CppUnit::TestSuite *suiteOfTests = new CppUnit::TestSuite("ThisIsATestSuite"); suiteOfTests->addTest(new CppUnit::TestCaller<MyTest>("test1", &MyTest::test1)); suiteOfTests->addTest(new CppUnit::TestCaller<MyTest>("test2", &MyTest::test2)); return suiteOfTests; } */ CPPUNIT_TEST_SUITE(MyTest); //define a TestSuite CPPUNIT_TEST(test1); //add test CPPUNIT_TEST(test2); //add test CPPUNIT_TEST_SUITE_END(); //end of TestSuite }; CPPUNIT_TEST_SUITE_REGISTRATION(MyTest); //register the TestSuite in this cpp file int main() { CppUnit::TestResult result; CppUnit::TextTestRunner r; //get the registry CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry(); //get all TestSuites in this registry r.addTest(registry.makeTest()); r.run("", true); return 0; }