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)
例子1,添加单个TestCase
#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类,用作运行测试并收集测试结果的实例。
编译的时候链接libcppunit和libdl两个动态库(当然也可以直接把.a编译到可执行文件里)
$ 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会报告测试的结果和错误的位置。
例子2,添加一个TestSuite
#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对象的指针。
一些帮助的宏
cppunit还定义了一些帮助的宏,便于使用者方便的添加TestSuite。
#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;
}
在这里,我们include了HelperMacros.h和TestFactoryRegistry.h。我们看到,在MyTest类里面,我们不需要再定义suite()函数,取而代之的是几个宏,很方便地就定义了一个TestSuite。另外,CPPUNIT_TEST_SUITE_REGISTRATION这个宏很方便地把这个文件里面的MyTest这个TestSuite注册了。这样,如果有多个测试类中定义了TestSuite,只要都使用这个宏,当调用CppUnit::TestFactoryRegistry::getRegistry()的时候就能够获取所有的TestSuite,非常方便。
分享到:
相关推荐
别人写的东东。。。单元测试初学者看看这个有帮助的,都是过来人了。。。
CPP UNIT source code study, also you can learn the design pattern used in CPPUnit
单元测试工具cppunit详细学习文档、用例单元测试工具cppunit详细学习文档、用例单元测试工具cppunit详细学习文档、用例
学习CppUnit 单元测试很好的教材,理论通俗易懂,结合简洁的实例。
CppUnit 是个基于 LGPL 的开源项目,最初版本移植自Unit,是一个非常优秀的开源测试框架。CppUnit 和 JUnit 一样主要思想来源于极限编程(XProgramming)。...如果答案是肯定的,就应该学习使用这种技术
cppunit使用详细说明,图文并茂,适合学习。
cppunit在linux下的安装配置及简单测试,适合新手入门学习cppunit
初学者学习cppunit的资料
主要内容: 背景 感性认识 基本理论 核心内容 三个例子分析 CppUnit源码解读 大部分资料来源于网上学习,感谢那些被我参考过的朋友^_^
学习IBM Rational Robot、IBM Purify、WinRunner、NUnit、JUnit、CPPUnit、Webstress、等各类软件测试工具,及Test Manager测试管理工具,针对所选系统实现情况,编写测试计划、设计测试用例,掌握软件自动测试方法...
该资源包含catch框架和博主自写的一个自动生成简单测试用例的工具,用起来简单,大家可以下载来学习使用,自写自动生成简单测试用例的工具包含有源码,可以根据此源码在添加自己的需求。 catch框架简介: 在catch的...
Zookeeper客户端调用库(已编译跨平台Release64位)及源码,如需重新编译,进入源码zookeeper-3.4.14\zookeeper-client\zookeeper-client-c中,按照cmake的常规...WANT_CPPUNIT ON),需要把ON设置为OFF,否则可能会报错)
主要内容: 软件测试基本理论 单元测试基本理论 为什么要进行单元测试 C/C++单元测试问答 单元测试工具 如何实施单元测试 所有内容来源于网上学习整理,仅供参考。欢迎多多交流。
可以学习研究、任意修改改进,但不可以换成其他作者另外发布,转载时请列出来源。 有改进意见可在博客地址或者邮件中提出。 博客:http://www.cnblogs.com/rhcad 邮件:rhcad@hotmail.com 详细描述见 ...