【转】CppUnit使用简介
以下内容来自:http://www.cnblogs.com/wishma/archive/2008/08/01/1258370.html
1. 简介
CppUnit 是个基于 LGPL 的开源项目,最初版本移植自 JUnit,是一个非常优秀的开源测试框架。CppUnit 和 JUnit 一样主要思想来源于极限编程(XProgramming)。主要功能就是对单元测试进行管理,并可进行自动化测试。这样描述可能没有让您体会到测试框架的 强大威力,那您在开发过程中遇到下列问题吗?如果答案是肯定的,就应该学习使用这种技术:
- 测试代码没有很好地维护而废弃,再次需要测试时还需要重写;
- 投入太多的精力,找 bug,而新的代码仍然会出现类似 bug;
- 写完代码,心里没底,是否有大量 bug 等待自己;
- 新修改的代码不知道是否影响其他部分代码;
- 由于牵扯太多,导致不敢进行修改代码;
2. 基本思想
对于上面的问题仅仅说明 CppUnit 的使用是没有效果的,下面先从测试的目的,测试原则等方面简要说明,然后介绍 CppUnit 的具体使用。
首先要明确我们写测试代码的目的,就是验证代码的正确性或者调试 bug。这样写测试代码时就有了针对性,对那些容易出错的,易变的编写测试代码;而不用对每个细节,每个功能编写测试代码,当然除非有过量精力或者可靠性要求。
编 码和测试的关系是密不可分的,推荐的开发过程并不要等编写完所有或者很多的代码后再进行测试,而是在完成一部分代码,比如一个函数, 之后立刻编写测试代码进行验证。然后再写一些代码,再写测试。每次测试对所有以前的测试都进行一遍。这样做的优点就是,写完代码,也基本测试完一遍,心里 对代码有信心。而且在写新代码时不断地测试老代码,对其他部分代码的影响能够迅速发现、定位。不断编码测试的过程也就是对测试代码维护的过程,以便测试代 码一直是有效的。有了各个部分测试代码的保证,有了自动测试的机制,更改以前的代码没有什么顾虑了。在极限编程(一种软件开发思想)中,甚至强调先写测试 代码,然后编写符合测试代码的代码,进而完成整个软件。
根据上面说的目的、思想,下面总结一下平时开发过程中单元测试的原则:
- 先写测试代码,然后编写符合测试的代码。至少做到完成部分代码后,完成对应的测试代码;
- 测试代码不需要覆盖所有的细节,但应该对所有主要的功能和可能出错的地方有相应的测试用例;
- 发现 bug,首先编写对应的测试用例,然后进行调试;
- 不断总结出现 bug 的原因,对其他代码编写相应测试用例;
- 每次编写完成代码,运行所有以前的测试用例,验证对以前代码影响,把这种影响尽早消除;
- 不断维护测试代码,保证代码变动后通过所有测试;
有上面的理论做指导,测试行为就可以有规可循。那么 CppUnit 如何实现这种测试框架,帮助我们管理测试代码,完成自动测试的?下面就看看 CppUnit 的原理。
3. cppunit的基本原理
CppUint进行测试的基本原理是:对于每一批测试,编写一个继承自TestFixture的测试类,其中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,将信息输出到信息输出栏,双击信息输出栏中一行,即可定位到出错位置。
4. 建立cppunit测试实例的一般步骤
建立一个cppunit测试实例的一般步骤如下:
- 包含文件#include <cppunit/extensions/HelperMacros.h>
- 声明一个类,比如,MathTest,继承自CppUnit::TestFixture。
- 声明setUp和tearDown函数。
- 声明测试函数,比如testAdd
- 如果含有其他测试函数,继续添加。
- 在类声明部分添加如下宏,声明改类为测试类,并且声明那些函数为测试函数
CPPUNIT_TEST_SUITE( MathTest); //声明一个TestSuite CPPUNIT_TEST( testAdd ); //添加TestCase到TestSuite /* 定义的TestCase需要在此声明。如果有其他TestCase,可以继续添加到此处 */ CPPUNIT_TEST_SUITE_END(); //TestSuite声明完成
7. 最后在实现的CPP文件中,添加下面的宏,用于注册测试类到某个测试项目,比如以"alltest"命名的项目。
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( MathTest, "alltest" );
8. 实现setUp和tearDown,以及各个测试函数。
6. cppunit的测试代码实例
需要测试的类名为Math,待测试的函数的Math::testAdd().
//Math.h
class Math{
public:
Math();
~Math();
int add(int, int);
};
//Math.cc
#include "Math.h"
int Math::add(int x, int y){
return x+y;
}
cppunit测试代码如下:
//MathTest.h
#include "cppunit/TestFixture.h"
#include "cppunit/extensions/HelperMacros.h"
class MathTest:public CppUnit::TestFixture{
CPPUNIT_TEST_SUITE(MathTest);
CPPUNIT_TEST(testAdd);
CPPUNIT_TEST_SUITE_END();
protected:
int m_value1, m_value2;
public:
MathTest(){}
void setUp();
void tearDown();
void testAdd();
};
//MathTest.cc
#include "MathTest.h"
#include "Math.h"
#include "cppunit/TestAssert.h"
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(MathTest, "alltest");
void MathTest::setUp(){
m_value1 = ;
m_value2 = ;
}
void MathTest::tearDown(){
}
void MathTest::testAdd(){
int ret = m_value1 + m_value2;
CPPUNIT_ASSERT(ret == );
}
测试的主代码如下:
#include "Math.h"
#include "MathTest.h"
#include <iostream>
#include "cppunit/ui/text/TestRunner.h"
#include "cppunit/extensions/TestFactoryRegistry.h"
int main(void){
CppUnit::TextUi::TestRunner runner;
CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry("alltest");
runner.addTest(registry.makeTest());
runner.run();
}
编译: g++ Math.cpp MathTest.cpp main.cpp -lcppunit -ldl -lm -lpthread -o mathTest
运行: ./mathTest
显示:
通过的情况:OK (1 tests)
失败的情况:会显示那个测试类中的哪行测试不通过
!!!FAILURES!!! Test Results: Run: 1 Failures: 1 Errors: 0 1) test: MathTest::testAdd (F) line: 15 MathTest.cpp assertion failed - Expression: ret==4
【转】CppUnit使用简介的更多相关文章
- Assignment3:白盒测试以及测试框架简介
一. 白盒测试简介 白盒测试又称结构测试.透明盒测试.逻辑驱动测试或基于代码的测试.白盒测试是一种测试用例设计方法,盒子指的是被测试的软件,白盒指的是盒子是可视的,你清楚盒子内部的东西以及 ...
- ASP.NET Core 1.1 简介
ASP.NET Core 1.1 于2016年11月16日发布.这个版本包括许多伟大的新功能以及许多错误修复和一般的增强.这个版本包含了多个新的中间件组件.针对Windows的WebListener服 ...
- MVVM模式和在WPF中的实现(一)MVVM模式简介
MVVM模式解析和在WPF中的实现(一) MVVM模式简介 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在 ...
- Cassandra简介
在前面的一篇文章<图形数据库Neo4J简介>中,我们介绍了一种非常流行的图形数据库Neo4J的使用方法.而在本文中,我们将对另外一种类型的NoSQL数据库——Cassandra进行简单地介 ...
- REST简介
一说到REST,我想大家的第一反应就是“啊,就是那种前后台通信方式.”但是在要求详细讲述它所提出的各个约束,以及如何开始搭建REST服务时,却很少有人能够清晰地说出它到底是什么,需要遵守什么样的准则. ...
- Microservice架构模式简介
在2014年,Sam Newman,Martin Fowler在ThoughtWorks的一位同事,出版了一本新书<Building Microservices>.该书描述了如何按照Mic ...
- const,static,extern 简介
const,static,extern 简介 一.const与宏的区别: const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 执行时刻:宏是预编 ...
- HTTPS简介
一.简单总结 1.HTTPS概念总结 HTTPS 就是对HTTP进行了TLS或SSL加密. 应用层的HTTP协议通过传输层的TCP协议来传输,HTTPS 在 HTTP和 TCP中间加了一层TLS/SS ...
- 【Machine Learning】机器学习及其基础概念简介
机器学习及其基础概念简介 作者:白宁超 2016年12月23日21:24:51 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...
随机推荐
- python中的commands模块
commands模块用于调用shell命令 有3中方法: commands.getstatus() 返回执行状态 commands.getoutput() 返回执行结果 commands.ge ...
- 1701. Ostap and Partners(并查集-关系)
1701 又是类似食物链的这一类题 这题是找与根节点的和差关系 因为0节点是已知的 为0 那么所有的都可以转换为与0的和差关系 可以规定合并的两节点 由大的指向小的 然后再更新和差关系 有可能最后有 ...
- 变量赋值(引用) php内核的实现(二)
<?php $a=1; $b=&$a; $c=2; $a=&$c; echo $a."\n"; echo $b; 2 1 结论: 首先保存 左值的内存地址, ...
- Oracle排序BUG
在今天项目开发中,遇到一个奇怪的问题,运用Oracle自身排序,然后将排序结果进行分页展示到前台时,发现数据有重复的现象. 这是数据表需要排序的全部结果,执行脚本:select * from ajb ...
- Azure 中的多个 VM NIC 和网络虚拟设备
YU-SHUN WANG Azure 网络高级项目经理 在 2014 年欧洲 TechEd 大会上,我们宣布了在Azure VM 中为多个网络接口 (NIC) 提供支持,并与多家重要厂商合作,在 Az ...
- 【转】Windows环境下Android NDK环境搭建
原文网址:http://www.metsky.com/archives/525.html 前面介绍Windows下Android 开发环境配置,主要是面向JAVA开发环境,对只做APK上层应用开发人员 ...
- 自杀程序&递归删除目录
自杀程序,删掉自身,包括执行程序所在的文件夹. 仅在windows下进行了测试,使用语言C# string fileName = Path.GetTempPath() + "killmyse ...
- 学习xcode 博客
csdn http://blog.csdn.net/tianyitianyi1/article/category/1160169/2
- HDU 1561-The more, The Better(树状背包)
题意: n个城堡,每个有一定的财富,有些城堡不能直接攻克,要攻克这些城堡必须先攻克其他某一个特定的城堡,求应攻克哪m个城堡,获得最大财富. 分析:dp[i][j],以i为根的子树,攻克j个城堡,获得的 ...
- ZOJ 3469 Food Delivery 区间DP
这道题我不会,看了网上的题解才会的,涨了姿势,现阶段还是感觉区间DP比较难,主要是太弱...QAQ 思路中其实有贪心的意思,n个住户加一个商店,分布在一维直线上,应该是从商店开始,先向两边距离近的送, ...