【转】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 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...
随机推荐
- 使用EventLog类写Windows事件日志
在程序中经常需要将指定的信息(包括异常信息和正常处理信息)写到日志中.在C#3.0中可以使用EventLog类将各种信息直接写入Windows日志.EventLog类在System.Diagnosti ...
- UVa 1641 ASCII Area
题意: 就是用一个字符矩阵代表一个闭合的阴影部分,然后求阴影部分的面积. 分析: 一个'/'和'\'字符都代表半个小方块的面积. 关键就是判断'.'是否属于阴影部分,这才是本题的关键. 从第一列开始, ...
- Building QT projects from the command line
/************************************************************************ * Building QT projects fro ...
- 【C++】【斐波那契】求第几个斐波那契数字。
首先在头文件 whichfibonaccinumber.h 中写了一个使用加法的解法.没有验证输入数字是否小于0. #ifndef WHICHFIBONACCINUMBER_H_ #define WH ...
- 【Grunt】
GRUNT The JavaScript Task Runnerhttp://gruntjs.com/ Grunt打造前端自动化工作流http://tgideas.qq.com/webplat/inf ...
- Maven使用教程
一.Maven介绍 我们在开发项目的过程中,会使用一些开源框架.第三方的工具等等,这些都是以jar包的方式被项目所引用,并且有些jar包还会依赖其他的jar包,我们同样需要添加到项目中,所有这些相关的 ...
- [转] windows7 IIS管理器 在计算机“.”上没有找到WAS服务
原文地址:windows7 IIS管理器 在计算机"."上没有找到WAS服务作者:云中的风 OS:windows7旗舰版 产生问题原因:运行金蝶K3-HR时客户端提示中间层服务器不 ...
- POJ2115 C Looooops 模线性方程(扩展欧几里得)
题意:很明显,我就不说了 分析:令n=2^k,因为A,B,C<n,所以取模以后不会变化,所以就是求(A+x*C)%n=B 转化一下就是求 C*x=B-A(%n),最小的x 令a=C,b=B-A ...
- CSLA.NET 简介
CSLA.NET 据说在国外用的很多,国内介绍这个框架的文章目前网络上能找到的比较早,大多是早期的一些版本的版本的介绍.目前最新版的4.5.6 .版本的整体架构已经有了很大的变化.拟开一个系列,结合〈 ...
- JSF session的用法
http://blog.csdn.net/finelife/article/details/1608632 1.写入sessionObject sessionName = "name&quo ...