CppUnit使用指南

如何使用CppUnit进行单元测试 导读: 一、前言   测试驱动开发(TDD)是以测试作为开发过程的中心,它坚持,在编写实际代码之前,先写好基于产品代码的测试代码。开发过程的目标就是首先使测试能够通过,然后再优化设计结构。测试驱动开发式是极限编程的重要组成部分。XUnit,一个基于测试驱动开发的测试框架,它为我们在开发过程中使用测试驱动开发提供了一个方便的工具,使我们得以快速的进行单元测试。XUnit的成员有很多,如JUn 阅读详情

测试驱动开发的原则:


先写测试代码,然后编写符合测试的代码。至少做到完成部分代码后,完成对应的测试代码;

测试代码不需要覆盖所有的细节,但应该对所有主要的功能和可能出错的地方有相应的测试用例;

发现 bug,首先编写对应的测试用例,然后进行调试;

不断总结出现 bug 的原因,对其他代码编写相应测试用例;

每次编写完成代码,运行所有以前的测试用例,验证对以前代码影响,把这种影响尽早消除;

不断维护测试代码,保证代码变动后通过所有测试;

在编码前:他可以强迫你对需求进行详细的分析。 

 在编码时:他可以使你对over coding保持警觉。

在重构时:可以确保新的设计能够兼容旧版本的功能。

在团队开发时:可以确保自己的单元是无误的。  


CppUnit的原理


在 CppUnit 中,一个或一组测试用例的测试对象被称为 Fixture(设施,下文为方便理解尽量使用英文名称)。Fixture 就是被测试的目标,可能是一个对象或者一组相关的对象,甚至一个函数。

 

有了被测试的 fixture,就可以对这个 fixture 的某个功能、某个可能出错的流程编写测试代码,这样对某个方面完整的测试被称为TestCase(测试用例)。通常写一个 TestCase 的步骤包括:

1.         对 fixture 进行初始化,及其他初始化操作,比如:生成一组被测试的对象,初始化值;

2.         按照要测试的某个功能或者某个流程对 fixture 进行操作;

3.         验证结果是否正确;

4.         对 fixture 的及其他的资源释放等清理工作。  


对 fixture 的多个测试用例,通常(1)(4)部分代码都是相似的,CppUnit 在很多地方引入了 setUp 和 tearDown 虚函数。可以在 setUp 函数里完成(1)初始化代码,而在 tearDown 函数中完成(4)代码。具体测试用例函数中只需要完成(2)(3)部分代码即可,运行时 CppUnit 会自动为每个测试用例函数运行 setUp,之后运行 tearDown,这样测试用例之间就没有交叉影响。 


撰写TestCase必须注意以下几点:

可以自动执行,不用人手操作。

自动返回测试结果。

绝对的独立,不能与其他TestCase有任何联系。就算测试同一个函数的不同功能也需要分开。每个TestCase可以说是一个孤岛。 


对 fixture 的所有测试用例可以被封装在一个 CppUnit::TestFixture 的子类(命名惯例是[ClassName]Test)中。然后定义这个fixture 的 setUp 和 tearDown 函数,为每个测试用例定义一个测试函数(命名惯例是 testXXX)。下面是个简单的例子: 


class MathTest : public CppUnit::TestFixture {

protected: 

       int m_value1, m_value2;  

 

public:

       MathTest() {}       

 

       // 初始化函数

       void setUp () {

              m_value1 = 2;

              m_value2 = 3;

       }

 

       // 测试加法的测试函数

       void testAdd () {

              // 步骤(2),对 fixture 进行操作

              int result = m_value1 + m_value2;

 

              // 步骤(3),验证结果是否争取

              CPPUNIT_ASSERT( result == 5 );

       }

 

       // 没有什么清理工作没有定义 tearDown.

}  


在测试函数中对执行结果的验证成功或者失败直接反应这个测试用例的成功和失败。CppUnit 提供了多种验证成功失败的方式:

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时失败

 

要把对 fixture 的一个测试函数转变成一个测试用例,需要生成一个 CppUnit::TestCaller 对象。而最终运行整个应用程序的测试代码的时候,可能需要同时运行对一个 fixture 的多个测试函数,甚至多个 fixture 的测试用例。CppUnit 中把这种同时运行的测试案例的集合称为 TestSuite。而 TestRunner 则运行测试用例或者 TestSuite,具体管理所有测试用例的生命周期。目前提供了 3 类TestRunner,包括:

CppUnit::TextUi::TestRunner        // 文本方式的TestRunner

CppUnit::QtUi::TestRunner            // QT方式的TestRunner

CppUnit::MfcUi::TestRunner         // MFC方式的TestRunner  


下面是一个TestRunner的例子:

CppUnit::TextUi::TestRunner runner;

  CppUnit::TestSuite *suite= new CppUnit::TestSuite(); 

 

  // 添加一个测试用例

  suite->addTest(new CppUnit::TestCaller<MathTest> (

         "testAdd", testAdd)); 

 

  // 指定运行TestSuite

  runner.addTest( suite );

 

  // 开始运行, 自动显示测试进度和测试结果

  runner.run( "", true );    // Run all tests and wait  


常用使用方式
按照上面的方式,如果要添加新的测试用例,需要把每个测试用例添加到 TestSuite 中,而且添加新的 TestFixture 需要把所有头文件添加到 main.cpp 中,比较麻烦。为此 CppUnit 提供了 CppUnit::TestSuiteBuilder,CppUnit::TestFactoryRegistry 和一堆宏,用来方便地把 TestFixture 和测试用例注册到 TestSuite 中。下面就是通常的使用方式(注意红色字体):

/// MathTest.h
#include "cppunit/extensions/HelperMacros.h"

 

class MathTest : public CppUnit::TestFixture {

       // 声明一个TestSuite

       CPPUNIT_TEST_SUITE( MathTest );

 

       // 添加测试用例到TestSuite, 定义新的测试用例需要在这儿声明一下

       CPPUNIT_TEST( testAdd );

 

       // TestSuite声明完成 

       CPPUNIT_TEST_SUITE_END();

 

       // 其余不变

protected:

       int m_value1, m_value2;

 

public:

       MathTest() {}

 

       // 初始化函数

       void setUp ();

 

       // 清理函数

       void tearDown();   

 

       // 测试加法的测试函数

       void testAdd ();

 

       // 可以添加新的测试函数

};

 

/// MathTest.cpp

// 把这个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 result = m_value1 + m_value2;

     CPPUNIT_ASSERT( result == 5 );

}

 

/// main.cpp
// 不用再包含所有TestFixture子类的头文件

#include <cppunit/extensions/TestFactoryRegistry.h>

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

 

// 如果不更改TestSuite, 本文件后期不需要更改.

int main()

{

       CppUnit::TextUi::TestRunner runner;   

 

       // 从注册的TestSuite中获取特定的TestSuite, 没有参数获取未命名的TestSuite.

CppUnit::TestFactoryRegistry &registry = CppUnit::TestFactoryRegistry::getRegistry("alltest");

 

//若没有注册名字,在MathTest.cpp文件中只是调用了CPPUNIT_TEST_SUITE_REGISTRATION( MathTest );那就可以写成

CppUnit::TestFactoryRegistry &registry = CppUnit::TestFactoryRegistry::getRegistry();

 

       // 添加这个TestSuite到TestRunner中

       runner.addTest( registry.makeTest() );

 

       // 运行测试

       runner.run();

}  


/// mainanother.cpp
另外的一种写法。其实和上面大同小异,只是生成的对象是Test而不是registry了。

int main(int argc, char* argv[])

{

  // Get the top level suite from the registry

  CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();

 

  // Adds the test to the list of test to run

  CppUnit::TextUi::TestRunner runner;

  runner.addTest( suite );

 

  // Change the default outputter to a compiler error format outputter

  runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(),

                                                       std::cerr ) );

 

  // Run the tests. 

  bool wasSucessful = runner.run();

 

  // Return error code 1 if the one of test failed.

  return wasSucessful ? 0 : 1;   

}

 

这样添加新的测试用例(TestFixture)只需要在类定义的开始声明一下即可。

 

其他实际问题


通常包含测试用例代码和被测试对象是在不同的项目中。应该在另一个项目(最好在不同的目录)中编写 TestFixture,然后把被测试的对象包含在测试项目中。
对某个类或者某个函数进行测试的时候,这个 TestFixture 可能引用了别的类或者别的函数,为了隔离其他部分代码的影响,应该在源文件中临时定义一些桩程序,模拟这些类或者函数。这些代码可以通过宏定义在测试项目中有效,而在被测试的项目中无效。  


CppUnit的组成结构


2 核心部分(Core)

2.1 基本测试类

2.1.1 Test

2.1.2 TestFixture

2.1.3 TestCase

2.1.4 TestSuite

 

2.2 测试结果记录

2.2.1 SynchronizedObject

2.2.2 TestListener

2.2.3 TestResult

 

2.3 错误处理

2.3.1 TestFailure

2.3.2 SourceLine

2.3.3 Exception

2.3.4 NotEqualException

 

2.4 断言

2.4.1 Asserter

2.4.2 TestAssert

 

3 输出部分(Output)

3.1 基础部件

3.1.1 Outputter

3.1.2 TestResultCollector

 

3.2 衍生类

3.2.1 TextOutputter

3.2.2 CompilerOutputter

3.2.3 XmlOutputter

 

4 辅助部分(Helper)

4.1 创建机制

4.1.1 TypeInfoHelper

4.1.2 TestFactory

4.1.3 TestFactoryRegistry,NamedRegistries

4.1.4 TestSuiteFactory

4.1.5 TestSuiteBuilder

4.1.6 TestCaller

4.1.7 AutoRegisterSuite

 

4.2 HelperMacros

 

5 扩展部分(Extension)

5.1 TestDecorator

5.2 RepeatedTest

5.3 Orthodox

5.4 TestSetUp

 

6 兼听者部分(Listener)

6.1 TestSucessListener

6.2 TextTestProgressListener

6.3 TextTestResult

 

7 界面部分(TextUI)

7.1 TestRunner

 

8 移植(Portability)

8.1 OStringStream

8.2 其他

CppUnit 使用指南 一,编译生成 lib,dll 文件 1.下载 CppUnit 源文件(这里用 1.12.0 版本,download from here: http://sourceforge.net/projects/cppunit/files/cppunit/ ) 2.解压后,进入其中的 src 目录(cppunit-1.12.0\src),打开 CppUnitLibraries.dsw, 编译其中的几个 阅读详情

相关推荐

matrix_cpp:C ++中可扩展矩阵的实现

矩阵C ++ C ++中可扩展矩阵的实现

cppunit 的使用

 1.  创建基于对话框的MFC项目:其他步骤,默认即可。2.  将cppunit所用的包拷入项目当前目录下。3.  添加cppunit目录为系统目录:4.  添加项目所依赖的lib库有:testrunner.lib 与 cppunitd.lib5.  准备好所要测试的类。6.  编写测试用例:1)  编写测试用例注册类,如:PlusTestSuit

wuzhifeng1211的专栏 646

使用cppunit 使用说明

使用cppunit 这是c++单元测试必备的资料。

CppUnit使用教程以及原理分析

1.     CppUnit用法简介 1.1.            基本用法 1.1.1.      使用TestCase类创建测试用例 如下代码所示: //定义测试用例类 class SimpleTestCase:publicCPPUNIT_NS::TestCase { public:     virtual voidrunTest()     {         int

yuanhong2910的专栏 7585

拆开一个烧坏的IGBT模块,手把手教你识别过压、过流、过温的“案发现场”

本文详细解析了IGBT模块失效分析的实战技巧,通过观察铝层熔化纹路、焊锡溢出形态等物理痕迹,手把手教你识别过压、过流、过温的典型失效模式。文章提供了从基础工具包到现场快速诊断的完整流程,帮助工程师精准定位IGBT模块失效的根本原因。

weixin_30655569的博客 426

PX4固件下VTOL固定翼的3种起飞方式对比:手抛vs弹射vs跑道

本文深度解析PX4固件下VTOL固定翼的三种起飞方式:手抛、弹射与跑道起飞,对比其技术差异与适用场景。通过详细的参数配置和工程实践指南,帮助开发者优化起飞性能,提升无人机在不同环境下的适应性和可靠性。文章特别针对PX4飞控系统的最新特性进行了技术探讨。

weixin_30296405的博客 87

CppUnit的安装及使用指南

转自:http://wenku.baidu.com/view/a0a5867f27284b73f242508a.html

xiaoxiaoyusheng2012的专栏 5292

从谱峰搜索到多项式求根:Root-MUSIC算法原理与MATLAB实践

本文深入解析Root-MUSIC算法在阵列信号处理中的原理与应用,通过多项式求根替代传统MUSIC算法的谱峰搜索,显著提升计算效率和精度。文章详细介绍了算法核心思想、MATLAB实现步骤及工程优化技巧,帮助读者掌握这一高效的DOA估计方法。

weixin_30832143的博客 80

cppUnit快速使用指南

【原文写于22 January 2007 ,注】 VC下cppUnit快速使用指南 编译打开cppUnit/src/CppUnitLibraries.dsw,build->batch build,全部build编译后得到所需库文件,在cppUnit/lib  安装将cppUnit/include加入到VC include目录将cppUnit/lib加入到VC li

shuiyu的blog 1288

Qt入门教程【环境搭建篇】Qt6+Mingw+QMake+QtCreator

Qt Windows平台安装

小鱼酱的博客 2万+

EZ-INSAR工具箱(使用历史问题)

把 rasterio 升到 1.3+(或退回 py39)→features能 import → 脚本能跑 → 出图 → MATLAB 不再报错!

2301_79258000的博客 121

CppUnit 快速使用指南

本文从开发人员的角度,介绍 CppUnit 框架,希望能够使开发人员用最少的代价尽快掌握这种技术。下面从基本原理,CppUnit 原理,手动使用步骤,通常使用步骤,其他实际问题等方面进行讨论。以下讨论基于 CppUnit1.8.0。 背景 CppUnit 是个基于 LGPL 的开源项目,最初版本移植自 JUnit,是一个非常优秀的开源测试框架。CppUnit 和 JUnit 一样主要思想来源于

xiao__C的专栏 681

[QMT量化交易小白入门]-104、QMT平台运行深度学习模型,预测期货价格

本专栏主要是介绍QMT的基础用法,常见函数,写策略的方法,也会分享一些量化交易的思路,大概会写100篇左右。QMT的相关资料较少,在使用过程中不断的摸索,遇到了一些问题,记录下来和大家一起沟通,共同进步。

木头大左的博客 484

CPPUnit 使用指南[Unix]

单元测试工具CPPUnit在Windows平台下使用图形界面,操作非常直观;但在Unix平台下,就需要花点功夫配置一番: 1.下载文件: 本人使用的是cppunit-1.12.0.rar 版本,可以在以下地址下载(http://u.115.com/file/f6a03bec8)共享有效期有一个月,这软件在网上也好找。如以上地址过期,未找到合适版本,请留言联系; 2.不用安装,直接将cppun

ColinOrg 681

Python爬虫实战:高效爬取CNKI知网文献数据的技术解析

本文将详细介绍如何使用Python最新技术构建一个高效的CNKI知网文献爬虫系统。我们将从爬虫基础知识讲起,逐步深入到高级反反爬技术、分布式爬取、智能解析等前沿内容。文章包含完整的代码实现,涵盖请求模拟、数据解析、持久化存储等关键环节,并特别针对CNKI的反爬机制提供解决方案。通过本文,读者将掌握构建专业级学术文献爬虫的全套技术栈。关键词:Python爬虫、CNKI爬取、反反爬技术、文献数据挖掘、Scrapy框架本文详细介绍了如何使用Python最新技术构建CNKI知网文献爬虫。

2201_76125261的博客 2075

【Scratch考级100图】图01-等级考试scratch绘 画正方形

一、案例介绍 小朋友们应该在数学课或者平时生活中有了解过正方形,正方形在我们生活中到处可见,那我们如果通过Scratch软件来绘制一个正方形呢,我们一起来学习一下吧,在舞台正中央绘制一个边长为200的正方形,要求: 1、围绕舞台中心绘制正多边形,均匀分布在四个象限中 2、正方形边长为200个单位,线条粗细、颜色自定 3、利用画笔绘制正方形,不能有多余的线条 二、案例演示 【Scratch案例演示】Scratch图1-画正方形 三、案例分析 当我们点击小绿旗启动程序后,舞台上会出现一个画

青少年编程学习指导 2670
上一篇: 重构-改善既有代码的设计总结
下一篇: IO重定向实现的Telnet
Matrix_Designer
博客等级 码龄16年 58粉丝 296原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值