CppUnit测试详解
一、 测试前的说明:
1、 对Fixture的一个测试函数转变成一个测试用例,需要生成一个CppUnit::TestCaller的对象。
有时可能运行一个Fixture的多个测试函数,甚至多个Fixture。CppUnit中把这种同时运行的测试案例的集合称为TestSuite。
而TestRunner则运行测试用例或者TestSuite,具体管理所有测试案例的生命周期,目前提供了一下3类TestRunner:
(1) CppUnit::TestUi::TestRunner//文本方式的TestRunner
(2) CppUnit::QtUi:: TestRunner//Qt方式的TestRunner
(3) CppUnit::MfcUi:: TestRunner//MFC方式
二、 测试分类
1、 不含宏的文本方式测试
2、 含宏的文本方式测试
3、 基于GUI的含宏的MFC的测试方式
三、 测试步骤
1、不含宏的文本测试
需包含 cppunitd_dll.dll、cppunitd_dll.lib库。
文本测试,就需要文本方式的TestRunner 如:CppUnit::TestUi::TestRunner。
Step1:首先完成测试函数的编写,测试类需要继承CppUnit::TestFixture,此类中有2个虚函数:void setup()和void teardown();
void setup() 完成初始化工作;
void teardown() 完成收尾的清理工作;
子类需实现这2个函数。
Step2:编写测试类的测试函数如testAdd();
Step3:编写被测试对象函数。
示例代码如下:
main.cpp
#include "MathTest.h"
#include "cppunit/TestSuite.h"
#include "cppunit/ui/text/TestRunner.h"
#include "cppunit/TestCaller.h"
#include <iostream>
using namespace std;
#pragma comment (lib, "cppunitd_dll.lib")
int main()
{
CppUnit::TextUi::TestRunnerrunner;
CppUnit::TestSuite*suite = new CppUnit::TestSuite();
//添加一个测试用例
suite->addTest(newCppUnit::TestCaller<MathTest>("testAdd",&MathTest::testAdd));
//指定运行TestSuite
runner.addTest(suite);
//开始运行,自动显示测试进度和测试结果
runner.run("",true);
return 0;
}
MathTest.h
#include "cppunit/TestFixture.h"
class MathTest:public CppUnit::TestFixture
{
public:
//初始化函数
void setUp();
//清理函数
voidtearDown();
//测试加法的测试函数
voidtestAdd();
protected:
intm_value1,m_value2;
};
MathTest.cpp
#define MATHTEST_H
#ifdef MATHTEST_H
#include "MathTest.h"
#include "cppunit/TestAssert.h"
#endif
void MathTest::setUp()
{
m_value1 = 2;
m_value2 = 3;
}
void MathTest::tearDown()
{
}
void MathTest::testAdd()
{
int ret =m_value1 + m_value2;
CPPUNIT_ASSERT(ret== 5);
}
2、含宏的文本方式测试
要方便添加测试代码,利用CppUnit提供的几个宏来进行:
//声明一个TestSuite
CPPUNIT_TEST_SUITE(MathTest);
//添加测试用例到TestSuite,定义新的测试用例需要在这里声明一下
CPPUNIT_TEST(testAdd);
//TestSuite声明完成
CPPUNIT_TEST_SUITE_END();
示例程序如下:
Main.cpp
#include<iostream>
using namespace std;
#include "cppunit/extensions/TestFactoryRegistry.h"
#include "cppunit/ui/text/TestRunner.h"
#pragma comment (lib, "cppunitd_dll.lib")
//如果不更改TestSuite,则本文件后期不需要更改
int main()
{
CppUnit::TextUi::TestRunnerrunner;
//从注册的TestSuite中获取待定的TestSuite,没有参数获取未命名的TestSuite
CppUnit::TestFactoryRegistry®istry = CppUnit::TestFactoryRegistry::getRegistry("alltest");
//添加这个TestSuite到TestRunner
runner.addTest(registry.makeTest());
//允许测试
runner.run();
return 0;
}
MathTest.h
/*使用宏的CPPUNIT*/
#include "cppunit/extensions/HelperMacros.h"
class MathTest:public CppUnit::TestFixture
{
//声明一个TestSuite
CPPUNIT_TEST_SUITE(MathTest);
//添加测试用例到TestSuite,定义新的测试用例需要在这里声明一下
CPPUNIT_TEST(testAdd);
//TestSuite声明完成
CPPUNIT_TEST_SUITE_END();
public:
//初始化函数
void setUp();
//清理函数
voidtearDown();
//测试加法的测试函数
void testAdd();
protected:
intm_value1,m_value2;
};
MathTest.cpp
#define MATHTEST_H
#ifdef MATHTEST_H
#include "MathTest.h"
#include "cppunit/TestAssert.h"
#endif
//把这个TestSuite注册到名为"alltest"的TestSuite中,如果未定义,则会自动定义
//也可以CPPUNIT_TEST_SUITE_REGISTRATION(MathTest);注册到全局的一个未命名的TestSuite中
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(MathTest,"alltest");
void MathTest::setUp()
{
m_value1 = 2;
m_value2 = 3;
}
void MathTest::tearDown()
{
}
void MathTest::testAdd()
{
int ret =m_value1 + m_value2;
CPPUNIT_ASSERT(ret== 5);
}
3、基于GUI的含宏的MFC的测试方式
建一个基于对话框的应用程序。
Step1: 首先需要建造窗口,在InitInstance()中注释掉如下代码:
/* CdialogCppUnitDlgdlg;
m_pMainWnd =&dlg;
INT_PTRnResponse = dlg.DoModal();
if (nResponse== IDOK)
{
// TODO: 在此放置处理何时用
// “确定”来关闭对话框的代码
}
else if (nResponse== IDCANCEL)
{
// TODO: 在此放置处理何时用
// “取消”来关闭对话框的代码
}
*/
编写自己的对话框:
CppUnit::MfcUi::TestRunner runner;
runner.addTest(PlusTest::suite());//添加测试
runner.run();//showui
Step2:编写测试用例,代码如下:
PlusTestCase.h
#pragma once
#include "cppunit/TestCase.h"
#include "cppunit/extensions/HelperMacros.h"
class CPlusTestCase :public CppUnit::TestCase
{
//声明一个TestSuite
CPPUNIT_TEST_SUITE(CPlusTestCase);
//添加测试用例到TestSuite,定义新的测试用例需要在这里声明一下
//CPPUNIT_TEST(testSort);
CPPUNIT_TEST(testAdd);
//TestSuite声明完成
CPPUNIT_TEST_SUITE_END();
public:
CPlusTestCase(void);
~CPlusTestCase(void);
voidtestAdd();//测试方法
//voidtestSort();//测试排序方法
void setUp();
voidtearDown();
};
PlusTestCase.cpp
#include "StdAfx.h"
#include "PlusTestCase.h"
#include "../dllMfcDlg/CPlus.h" //20130327
//#include "../intSort/CCSort.h" //20130327
#pragma comment (lib, "cppunitd_dll.lib")
#pragma comment(lib,"E:\\workStudyDocu\\CppUnit\\2008cppunit-lib-dll_32\\testrunnerud.lib")
#pragma comment (lib,"E:\\workStudyDocu\\CppUnit\\2008cppunit-lib-dll_32\\cppunitd.lib")
//#pragma comment(lib,"E:\\workStudyDocu\\CppUnit\\2008cppunit-lib-dll_32\\testrunnerd.lib")
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(CPlusTestCase,"plus");//注册一个名为plus的TestSuite
//CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(CPlusTestCase,"sort");
CPlusTestCase::CPlusTestCase(void)
{
}
CPlusTestCase::~CPlusTestCase(void)
{
}
void CPlusTestCase::testAdd()
{
CCPlusplus;//被测对象的类
int nret =plus.Add(10,20);
CPPUNIT_ASSERT_EQUAL(30,nret);
}
void CPlusTestCase::setUp()
{
}
void CPlusTestCase::tearDown()
{
}
Step3:编写命名空间,代码如下:
CPlusTestSuite.h
#include "cppunit/extensions/TestFactoryRegistry.h"
namespace PlusTest
{
CppUnit::Test*suite()
{
CppUnit::TestFactoryRegistry®istry = CppUnit::TestFactoryRegistry::getRegistry("plus ");
returnregistry.makeTest();//
}
}
// 说明: Step1 中的PlusTest::suite()返回一个指向CppUnit::Test的指针,这个指针就是整个测试的起点。CppUnit::TestFactoryRegistry::getRegistry()根据TEstSuite的名称返回TestFactoryRegistry工厂,然后调用工厂里的makeTest()对TestSuite进行组装。
Step4 编写被测函数的代码:
如以下代码:
CPlus.h
#pragma once
class AFX_EXT_CLASS CCPlus
{
public:
CCPlus(void);
~CCPlus(void);
intAdd(int,int);
};
CPlus.cpp
#include "StdAfx.h"
#include "CPlus.h"
CCPlus::CCPlus(void)
{
}
CCPlus::~CCPlus(void)
{
}
int CCPlus::Add(int num1,int num2)
{
return num1 +num2;
}