测试驱动开发(TDD)是以测试作为开发过程的中心,它坚持,在编写实际代码之前,先写好基于产品代码的测试代码。开发过程的目标就是首先使测试能够通过,然后再优化设计结构。测试驱动开发式是极限编程的重要组成部分。XUnit,一个基于测试驱动开发的测试框架,它为我们在开发过程中使用测试驱动开发提供了一个方便的工具,使我们得以快速的进行单元测试。XUnit的成员有很多,如JUnit,PythonUnit等。今天给大家介绍的CppUnit即是XUnit家族中的一员,它是一个专门面向C++的测试框架。
用CppUint进行测试时,一般先以某个函数或者某个类作为测试单元,完成测试;在完成这些基本的测试后,再将引用到测试过的这些函数或者类的函数或者类,作为测试单元完成测试;继续下去,从而完成整个模块甚至是整个系统的测试,从而达到更多清除bug的目的。
一、CppUnit测试框架
CppUnit测试框架的源代码可以到 http://sourceforge.net/projects/cppunit/ 上下载。下载解压后,你将看到如下文件夹:

主要的文件夹有:
- doc: CppUnit的说明文档。另外,代码的根目录,还有三个说明文档,分别是INSTALL,INSTALL-unix,INSTALL-WIN32.txt。
- examples: CpppUnit提供的例子,也是对CppUnit自身的测试,通过它可以学习如何使用CppUnit测试框架进行开发。
- include: CppUnit头文件。
- src: CppUnit源代码目录。
二、基本原理
CppUint进行测试的基本原理是:对于每一批测试,编写一个继承自TestCase的测试类,其中setUp和tearDown 两个虚函数分别用于进行测试数据的初始化和释放操作;对于每一项测试,分别定义一个void返回类型的无参数方法,检测测试过程,可以用以下几个宏:
CPPUNIT_ASSERT(condition)
|
断言condition为真,否则失败
|
CPPUNIT_ASSERT_MESSAGE(message,condition)
|
当condition为假时失败, 并打印message
|
CPPUNIT_FAIL(message)
|
当前测试失败, 并打印message
|
CPPUNIT_ASSERT_EQUAL(expected, actual)
|
确信两者相等,否则失败
|
CPPUNIT_ASSERT_EQUAL_MESSAGE(message, expected, actual)
|
确信两者相等,否则失败,并同时打印message
|
CPPUNIT_ASSERT_DOUBLES_EQUAL(expected, actual, delta)
|
当expected和actual之间差大于delta时失败
|
其中,“失败”的含义就是程序运行出现异常,并且所有测试过程中止。
在完成一个或者多个测试类的编写后,需要用TestRunner类的实例来运行每个测试类的测试函数进行测试。TestRunner类型共有:TextUi::TestRunner,QtUi::TestRunner,MfcUi::TestRunner三个,都可以用来运行测试,其区别为:
TextUi::TestRunner
|
默认将信息输出到控制台,也可以指定输出到std::ostringstream。
|
QtUi::TestRunner
|
用QT的GUI输出信息
|
MfcUi::TestRunner
|
用MFC的GUI输出信息
|
整个测试过程需要另外附加代码,所以通常情况下,测试用例代码和被测试对象因在不同的项目中。应该在另一个项目(最好在不同的目录)中编写测试类,然后把被测试的对象包含在测试项目中。根据测试工程建立的类型,Consol可以选择TextUi::TestRunner,将结果输出至控制台显示,MFC的GUI可以使用MfcUi::TestRunner,使用GUI来控制并查看测试结果。测试工程与被测试对象所在工程的类型是可以不同的。
在使用VC作为开发工工具时,建议使用TextUi::TestRunner,并更改其Outputter实例,使用附加的TraceOutputter,将信息输出到信息输出栏,双击信息输出栏中一行,即可定位到出错位置。
三、安装方式
以VC使用为例,步骤如下:
1. 获取原始包,比如cppunit-1.12.1.rar,解压缩到某个目录,比如E:\cppunit-1.12.1
2. 将MsDevCallerListCtrl.cpp文件中的
#import "libid:80cc9f66-e7d8-4ddd-85b6-d9e6cd0e93e2" version("7.0") lcid("0") raw_interfaces_only named_guids
改为:(VC2008,version("9.0");VC2005,version("8.0"))
#import "libid:80cc9f66-e7d8-4ddd-85b6-d9e6cd0e93e2" version("9.0") lcid("0") raw_interfaces_only named_guids
编译工程,编译完成之后会在lib目录下生成cppunit、TestRunner等lib/dll文件。
2. 打开VC,菜单“工具” -> “选项”,在“选项”对话框的“项目和解决放方案”页中,包含文件include Files添加“E:\cppunit-1.12.1\include”,库文件Library Files添加“E:\cppunit-1.12.1\lib”。如图:


3. 打开工程E:\cppunit-1.12.1\src\CppUnitLibraries.dsw,在该工程中,cppuint是静态库版本,cppunit_dll是动态库版本,一般只需要完成release版本编译,如果想要研究源代码,可以考虑编译debug版本,用于调试和跟踪代码。
4. 如要使用MfcUi::TestRunner,编译dsplugin工程和TestRunner工程。dsplugin是一个VC的插件,TestRunner就是MfcUi::TestRunner的实现。
5、将CppUnitTestApp工程设为Active Project(Win32 Debug),编译后运行,则可以看到CppUnit的基于GUI方式进行单元测试TestRunner的界面。点击“Run”,将会看到如图所示界面:

点击“Browse”,我们还可以选择想要进行的单元测试,如图:

四、使用方法
CppUnit最小的测试单位是TestCase,多个相关TestCase组成一个TestSuite。要添加测试代码最简单的方法就是利用CppUnit为我们提供的几个宏来进行(当然还有其他的手工加入方法,但均是殊途同归,大家可以查阅CppUnit头文件中的演示代码)。这几个宏是:
CPPUNIT_TEST_SUITE() 开始创建一个TestSuite
CPPUNIT_TEST() 添加TestCase
CPPUNIT_TEST_SUITE_END() 结束创建TestSuite
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION() 添加一个TestSuite到一个指定的TestFactoryRegistry工厂 。(两个参数:第一个是TestSuite;第二个是唯一标识TestSuite名称字符串)
CppUnit::MfcUi::TestRunner runner;// MFC的GUI测试控制平台
CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry(TestSuite名称);//得到标识TestSuite名称字符串TestFactoryRegistry
runner.addTest(registry.makeTest());//添加Test
runner.run();//运行测试案例
///////////////////////////////////////////////////////////////////////实例:一个实现两个整数加减乘除运算的类测试
// Arithmetic.h 加减乘除运算类
#pragma once
class CArithmetic
{
public:
CArithmetic(void);
~CArithmetic(void);
public:
int Add(int nNum1, int nNum2);
int Sub(int nNum1,int nNum2);
int Mul(int nNum1,int nNum2);
double Div(int nNum1,int nNum2);
};
// Arithmetic.cpp
#include " Arithmetic.h"
CArithmetic::CArithmetic(void)
{
}
CArithmetic::~CArithmetic(void)
{
}
int CArithmetic::Add(int nNum1, int nNum2)
{
return nNum1+nNum2;
}
int CArithmetic::Sub(int nNum1,int nNum2)
{
return nNum1-nNum2;
}
int CArithmetic::Mul(int nNum1,int nNum2)
{
return nNum1*nNum2;
}
double CArithmetic::Div(int nNum1,int nNum2)
{
return nNum1/(nNum2*1.0);
}
在Project中加入一个类,取名CArithmeticTestCase,CArithmeticTestCase从CppUnit::TestCase继承,代码如下:
//ArithmeticTestCase.h
#pragma once
#include "cppunit/extensions/HelperMacros.h"
class CArithmeticCase : public CppUnit::TestCase
{
CPPUNIT_TEST_SUITE(CArithmeticCase);
CPPUNIT_TEST(testAdd);
CPPUNIT_TEST(testSub);
CPPUNIT_TEST(testMul);
CPPUNIT_TEST(testDiv);
CPPUNIT_TEST_SUITE_END();
public:
CArithmeticCase(void);
~CArithmeticCase(void);
void testAdd();
void testSub();
void testMul();
void testDiv();
virtual void setUp();
virtual void tearDown();
};
// ArithmeticTestCase.cpp
#include "StdAfx.h"
#include "ArithmeticTestCase.h"
#include "Plus.h"
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(CArithmeticTestCase,"MyArithmeticTest");
CArithmeticTestCase::CArithmeticTestCase(void)
{
}
CArithmeticTestCase::~CArithmeticTestCase(void)
{
}
void CArithmeticTestCase::testAdd()
{
CArithmetic plus;
int nResult = plus.Add(10, 20);
CPPUNIT_ASSERT_EQUAL(30, nResult);
}
void CArithmeticTestCase::testSub()
{
CArithmetic plus;
int nResult = plus.Sub(10, 20);
CPPUNIT_ASSERT_EQUAL(-10, nResult);
}
void CArithmeticTestCase::testMul()
{
CArithmetic plus;
int nResult = plus.Mul(10, 20);
CPPUNIT_ASSERT_EQUAL(200, nResult);
}
void CArithmeticTestCase::testDiv()
{
CArithmetic plus;
double fResult = plus.Div(10, 20);
CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5, fResult,0.000001);
}
void CArithmeticTestCase::setUp()
{
//初始化一些共用信息,比如全局变量,资源等。
TRACE("Enter CPlusTestCase::setUp()\n");
}
void CArithmeticTestCase::tearDown()
{
//析构处理一些信息,比如释放资源
TRACE("Enter CPlusTest::tearDown()\n");
}
测试代码编写
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/mfc/TestRunner.h>
#pragma comment(lib, "cppunitd.lib")
#pragma comment(lib, "testrunnerud.lib")//可以加载静态库,比动态库DEBUG版本,具体参考cppunit-1.12.1\lib下的文件。
CppUnit::MfcUi::TestRunner runner;
CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry("MyArithmeticTest");
runner.addTest(registry.makeTest());
runner.run();
代码:http://download.csdn.net/source/2556833
分享到:
相关推荐
2. **配置VS2008项目**:在VS2008中新建一个空的解决方案,然后添加一个新的Win32控制台应用程序项目。选择“静态库”作为项目类型,因为cppunit通常被用作库来链接到你的测试代码。 3. **添加源文件**:将cppunit...
cppunit是核心的测试框架,VS2008是开发环境,"wizard"是指在VS2008中用于简化cppunit项目创建的向导工具,"工程向导"则是指该工具在创建新工程时的作用,而“unicode”再次突出了此次升级的重要更新。 在压缩包的...
总之,"cppunit wizard for vs2008 sp1"是帮助开发者在VS2008 SP1环境中快速集成和使用CppUnit测试框架的工具,通过遵循提供的安装步骤和参考源代码示例,可以有效地进行单元测试,确保代码质量。
cppunit-1.12.1是一个开源的C++测试框架,主要用于编写和执行单元测试。这个版本是使用Microsoft Visual Studio 2010(vc2010)编译的,包含了预编译的动态链接库(dll)和静态库(lib),以及cppunit的完整源代码。...
CPPUnit是从JUnit(Java编程语言中的单元测试框架)移植过来的,它提供了类似于JUnit的接口和结构,使得C++开发者可以方便地进行单元测试。CPPUnit的主要组件包括测试套件(Test Suite)、测试案例(Test Case)、...
在探讨Visual Studio 2010配合CppUnit进行单元测试的配置和应用时,我们首先需要了解一些基础知识,包括CppUnit单元测试框架的基本概念、Visual Studio 2010的环境配置,以及如何在Windows 7操作系统上将两者结合...
CppUnit是一个强大的C++单元测试框架,广泛应用于软件开发的验证阶段,特别是在电子设计自动化(EDA)和可编程逻辑设备(PLD)领域,它可以帮助开发者确保代码的正确性和稳定性。下面是使用CppUnit进行单元测试的...
通过这些资源,开发者可以学习到如何在C++项目中应用TDD,包括如何选择和设置测试框架,如何编写测试用例,以及如何利用测试驱动来指导功能代码的实现。同时,了解单元测试的模式和最佳实践能够帮助提高测试的质量和...
8. CppUnit:类似于Java的JUnit,是C++的单元测试框架,用于编写和执行测试用例,确保代码质量。 9. Loki:这是一个实验性质的库,试图通过模板库的方式实现设计模式,为C++开发者提供更高级别的抽象。 10. FC++:...
应用程序可以基于X3插件框架进行快速开发,X3插件框架中的插件既可以单独使用,又可以灵活组合使用。X3插件框架采用VC++开发,没有使用MFC、ATL、COM,已经过3年十几个系统的实际使用验证。 目前X3插件框架包括插件...
8. **CppUnit**:一个C++的单元测试框架,与Java的JUnit类似,用于编写和执行单元测试,确保代码的质量。 9. **Loki**:这是一个实验性质的库,探索如何通过模板将设计模式转化为可以直接使用的库组件。 10. **FC+...
CppUnit 是一个C++单元测试框架,类似于Java的JUnit。它提供了一套方便的API来编写和运行测试案例,帮助开发者确保代码的质量和稳定性。CppUnit的一个重要特点是它与C++标准库紧密集成,因此可以很容易地在现有项目...
**简介**: CppUnit 是一个用于C++语言的单元测试框架,灵感来源于JUnit。它帮助开发者编写和运行测试用例,确保代码质量。 **特点**: - 自动化测试:支持自动化执行测试用例,减少人工干预。 - 报告生成:能够生成...
- **简介**:CppUnit 是一个类似于 Java 的 JUnit 的 C++ 单元测试框架,用于自动化测试 C++ 代码。 - **特点**: - 支持测试驱动开发(TDD)的方法论。 - 提供了断言机制来验证预期结果。 - 有助于提高代码质量...