分享
 
 
 

使用CppUnit进行单元测试

王朝other·作者佚名  2006-01-10
窄屏简体版  字體: |||超大  

一. CppUnit的安装

http://sourceforge.net/projects/cppunit CppUnit的源码包. CppUnit是开源产品 , 当前最高版本为1.11.0. (在上面的链接所指向的页面上选择 Development Snapshot ).

下载后,将源码包解压缩到本地硬盘. 以C:为例, 解压到C:\CppUnit-1.11.0 . 接下来进行编译工作. 在src/目录下, 将CppUnitLibraries.dsw工程文件用vc 打开. 因为这个工程是vc6建的工程, 所以会提示是否将此工程转为vc.net的工程格式. 选择"全是"就行. 然后在"生成"菜单中选择"生成解决方案",编译整个工程.

编译通过以后, 在lib/目录下,会生成若干lib,和dll文件, 都以cppunit开头. cppunitd表示debug版, cppunit表示release版.

然后配置vc环境: 工具菜单->选项->项目->vc++目录, 将C:\cppunit-1.11.0\include加入到vc 的 头文件目录中. 将C:\cppunit-1.11.0\lib 加入到vc的 连接库目录中. 然后将 C:\cppunit-1.11.0\lib路径加入到系统路径中(因为我们的测试程序需要cppunit的dll文件,所以要dll所在路径加入到系统路径(path)变量中, 或者将这些文件拷贝到系统目录中也可以).

二. CppUnit 的使用

以上工作完成以后,就可以正式使用CppUnit了.

我们新建一个控制台工程, 假定工程名为TDD1. 假设我们将在这个工程下开发, 那么根据测试驱动的原理,我们需要先建立一个单元测试框架. 在CppUnit下, 可以选择控制台方式和UI方式两种表现方案.我们选择UI方式. 那么现在在原来工程的基础上,再新增加一个对话框工程. 假设名为:Unit_Test .

在CppUnit中, 是以TestCase为最小的测试单位, 若干TestCase组成一个TestSuite. 所以我们要先建立一个TestCase.

新建一个类, 命名为CTestCase , 让其从CppUnit::TestCase派生. 为其新增一个方法,假设为 void doTest(); 我们将在这个函数中写入我们的一些测试代码. 切记要包含头文件

#include <CppUnit/extensions/HelperMacros.h>

class CTestCase : public CppUnit::TestCase

{

public:

CTestCase(void);

~CTestCase(void);

void doTest();

};

接下来, 我们要对我们的TestCase进行声明. 声明用到了三个宏.

CPPUNIT_TEST_SUITE();

CPPUNIT_TEST();

CPPUNIT_TEST_SUITE_END();

第一个宏声明一个测试包,第二个宏声明一个测试用例. 现在我们的CTestCase类看上去象这样.

class CTestCase : public CppUnit::TestCase

{

CPPUNIT_TEST_SUITE(CTestCase);

CPPUNIT_TEST(doTest);

CPPUNIT_TEST_SUITE_END();

public:

CTestCase(void);

~CTestCase(void);

void doTest();

};

接下来,我们要注册我们的测试suite. 使用CPPUNIT_TEST_SUITE_NAMED_REGISTRATION()来注册一个测试suite. 这个宏的第二个参数是我们注册的suite的名字. 在这里我们可以用字符串来代替, 但我们用一个静态函数来返回这个suite的名字.

//TestCase.h

static std::string getSuiteName();

//TestCase.cpp

std::string CTestCase::getSuiteName()

{

return "TDDExample3";

}

记得要在TestCase.h中包含 #include <string>

然后在 TestCase.cpp注册我们的suite.

CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(CTestCase , CTestCase::getSuiteName() );

接下来我们写一个注册函数, 使其在运行期生成一个Test.

static CppUnit::Test* getSuite();

CppUnit::Test* CTestCase::getSuite()

{

CppUnit::TestFactoryRegistry& reg =

CppUnit::TestFactoryRegistry::getRegistry ( CTestCase::getSuiteName() );

return reg.makeTest();

}

记住包含头文件:

#include <cppunit/extensions/TestFactoryRegistry.h>

最后, 我们的单元测试建立一个UI测试界面.

我们在CUnit_TestApp::InitInstance()函数中,将原先显示主对话框的代码以下面的代码取代:

CppUnit::MfcUi::TestRunner runner;

runner.addTest(CTestCase::getSuite());

runner.run();

必须先包含头文件:

#include <cppunit/ui/mfc/TestRunner.h>

#include "TestCase.h"

到此为止, 我们已经建立好一个简单的单元测试框架. 我们可以在doTest()中加入我们的测试代码,来进行测试了. CppUnit会将测试结果通过一个界面显示出来.

但此时我们虽然能编译通过,但在连接时会发生错误. 所以将下面两个库加入到工程中. 也可以在TestCase.h 中显式的加入:

#pragma comment(lib,"cppunit.lib")

#pragma comment(lib,"testrunnerd.lib")

下面是完整的程序清单:

//TestCase.h

#pragma once

#include <string>

#include <CppUnit/extensions/HelperMacros.h>

#include <cppunit/extensions/TestFactoryRegistry.h>

#include <cppunit/Asserter.h>

#pragma comment(lib,"cppunit.lib")

#pragma comment(lib,"testrunnerd.lib")

class CTestCase : public CppUnit::TestCase

{

CPPUNIT_TEST_SUITE(CTestCase);

CPPUNIT_TEST(doTest);

CPPUNIT_TEST_SUITE_END();

public:

static std::string getSuiteName();

static CppUnit::Test* getSuite();

public:

CTestCase(void);

~CTestCase(void);

void doTest();

};

//TestCase.Cpp

#include "StdAfx.h"

#include ".\testcase.h"

CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(CTestCase , CTestCase::getSuiteName() );

CTestCase::CTestCase(void)

{

}

CTestCase::~CTestCase(void)

{

}

void CTestCase::doTest()

{

}

std::string CTestCase::getSuiteName()

{

return "TDDExample3";

}

CppUnit::Test* CTestCase::getSuite()

{

CppUnit::TestFactoryRegistry& reg =

CppUnit::TestFactoryRegistry::getRegistry( CTestCase::getSuiteName() );

return reg.makeTest();

}

//Unit_Test.cpp

#include <cppunit/ui/mfc/TestRunner.h>

#include "TestCase.h"

BOOL CUnit_TestApp::InitInstance()

{

InitCommonControls();

CWinApp::InitInstance();

AfxEnableControlContainer();

CppUnit::MfcUi::TestRunner runner;

runner.addTest(CTestCase::getSuite());

runner.run();

return FALSE;

}

现在编译,运行, 如图一:

进度条呈现绿色, 表示我们此次测试通过. 事实上我们的doTest是一个空函数,什么代码也没有写,当然能通过了. :)

下面我们在doTest()中加点代码进去.

char* p = NULL; p[0]='c';

这段代码会引起一个访问异常. 看UnitCpp怎么来报告这段代码的错误.

编译,运行如图2:

这时CppUnit会告诉我们dotest出现一个错误. 并提供了错误的一些信息.

这样我们用CppUnit搭建一个简单单元测试框架.

参考文章:

CppUnit测试框架入门

作者Blog http://blog.csdn.net/cpluser/

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有