以前编写程序从没有做过单元测试的工作,所以在后期会花很多时间去纠错,这也就是软件工程中的2:8定律。最近要完成一个项目,要求要对系统中的主类和主函数作出单元测试的保证,才去查找了相关方面的资料,看过后觉得单元测试在工程中是必不可少的一项,下面就对有关C++的单元测试做一个简单的介绍,因为本人还没有系统的去理解相关方面的内容,所以只是介绍一些简单的应用和浅显的原理,有不到之处还请指出:

1) 什么是单元测试

单元测试(unit test,模块测试又称白盒测试)是开发者编写的一小段代码,用于检测被测代码的一个很小的,很明确的功能是否正确,通过编写单元测试可以在编码阶段发现程序编码错误,甚至是程序设计错误。现在回想下我们平时编程的过程:梳理逻辑->编写代码->调bug的一个循环过程;其中调试bug是一个很耗费时间的过程,而且调完一堆bug后我们对自己程序的信任度却在不断降低,因为不知道还会不会出bug。这是因为我们所调试的bug只是当前出现的,没有出现的呢,我们就说不好了。我们知道程序中一个简单的if...else...语句都会对数据流有一次分类,不同类的数据流所对应的操作不同,想想这些你就会觉得自己的代码还不知道要出多少bug。单元测试却很好的解决了这个问题,你要做的就是对核心的函数,核心的逻辑,将所有可能的数据流都列出来,进行一次全覆盖测试,这样你代码的健壮性就会很强。

2)如何写单元测试

最简单的方法那就是自己将核心的函数抽出来,重新建立一个项目,提供所有可能的数据流入口,对函数进行测试。这样做有两个缺陷:1、只能处理一些简单的项目,对于逻辑较为复杂,数据分支较多的就无法操作了;2、没有一个很好的框架,写出的代码没有一个统一的规则,可读性不强;为此,依托一个现有的测试框架是必不可少的。CppUnit是xunit家族的一员,xunit是一种测试框架,最早是在smalltalk上实现,后来被广泛的在各种语言上实现,除了Cppunit还有NUnit(c#版本)phpunit(php版本)和CppUnit相似的gtest(google的C++测试工具,据说在应用上要优于CppUnit,没有用过,大家可以试试),cmockery(c语言测试工具,也是google的)。cppunit以源码的方式发布,所以想要使用这个工具就要自己下载编译(后面会介绍到),同时在windows下CppUnit还带了一个MFC项目,可以以图形界面的方式报告编译情况。

3)如何编译CppUnit

我的编译环境是win7,vs2010;

1 :下载源码包 最新的版本是1.21.1(2008年最后一次更新)

地址 :http://sourceforge.net/projects/cppunit/ 或者直接点击 http://sourceforge.net/projects/cppunit/files/cppunit/1.12.1/cppunit-1.12.1.tar.gz/download

2 : 复制cppunt-1.12.1到c:\解压得到目录C:\cppunit-1.12.1

3 : 进入C:\cppunit-1.12.1\src 用VS2010打开CppUnitLibraries.dsw提示转换,转换之

4 : 在项目列表看见一堆项目,默认是以Debug的方式编译,如以该方式编译需要修改目标文件名

cppunit                $(ProjectName)   ->   $(ProjectName)d
cppunit_dll           $(ProjectName)   ->   cppunitd_dll
DllPlugInTester     $(ProjectName)   ->   $(ProjectName)d_dll
TestPlugInRunner $(ProjectName)   ->   $(ProjectName)d
TestRunner          $(ProjectName)  ->   $(ProjectName)d

需要修改目标文件名的原因是上述项目都设置了生成事件,在生成以后都会把生成的文件复制到lib目录下,个人判断d应该是代表了测试版的意思,如果是Release版本生成的目标文件都是项目名不需要修改

5 : 修改DSPlugIn入口
属性,配置属性,链接器,高级,无入口点 设置是

6 : 修改无法加载类型库(编译TestPlugInRunner,TestRunner)会报错其中7.0修改为8.0
#import "libid:80cc9f66-e7d8-4ddd-85b6-d9e6cd0e93e2" version("7.0") lcid("0") raw_interfaces_only named_guids

以上设置都全做完以后就可以整体编译解决方案了(这里要注意一点,要将上述所有的配置实现后再编译,不要对每个项目进行单独编译;否则会出现诸如“该文件没有一个关联的程序...”这样的问题)

4)如何用Cppunit

先写一个测试的Demo,初步体验下Cppunit的用法

1、打开vs2010文件项, 新建VC++空项目:cppUnitTest

2、 设置环境变量;在系统变量PATH的尾巴上添加“C:\cppunit-1.12.1”(这是我的地址)

3、 [项目cppUnitTest]-[属性]-[配置属性]-[C/C++]-[常规]-[附加包含目录]: "../include"

4、 [项目cppUnitTest]-[属性]-[配置属性]-[链接器]-[常规]-[附加库目录]: "../lib"

5、 [项目cppUnitTest]-[属性]-[配置属性]-[链接器]-[输入]-[附加依赖项]: "cppunitd.lib"

6、新建文件main.cpp

#include <cppunit/TestCase.h>
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/TextOutputter.h>
#include <cppunit/TestCaller.h>
#include <cppunit/TestRunner.h> // 定义测试类
class StringTest : public CppUnit::TestFixture
{
public:
void setUp() // 初始化
{
m_str1 = "Hello, world";
m_str2 = "Hi, cppunit";
} void tearDown() // 清理
{
} void testSwap() // 测试方法1
{
std::string str1 = m_str1;
std::string str2 = m_str2;
m_str1.swap(m_str2); CPPUNIT_ASSERT(m_str1 == str2);
CPPUNIT_ASSERT(m_str2 == str1);
} void testFind() // 测试方法2
{
int pos1 = m_str1.find(',');
int pos2 = m_str2.rfind(','); CPPUNIT_ASSERT_EQUAL(, pos1);
CPPUNIT_ASSERT_EQUAL(, pos2);
} protected:
std::string m_str1;
std::string m_str2;
}; int main(int argc, char* argv[])
{
CppUnit::TestResult r;
CppUnit::TestResultCollector rc;
r.addListener(&rc); // 准备好结果收集器 CppUnit::TestRunner runner; // 定义执行实体
runner.addTest(new CppUnit::TestCaller<StringTest>("testSwap", &StringTest::testSwap)); // 构建测试用例1
runner.addTest(new CppUnit::TestCaller<StringTest>("testFind", &StringTest::testFind)); // 构建测试用例2
runner.run(r); // 运行测试 CppUnit::TextOutputter o(&rc, std::cout);
o.write(); // 将结果输出 return rc.wasSuccessful() ? : -;
}

以上代码时使用Cppunit框架对string类的两个函数进行测试,在testFind()中调用string的find函数并通过CPPUNIT_ASSERT对结果进行测试;

C++之单元测试的更多相关文章

  1. Intellij idea添加单元测试工具

    1.idea 版本是14.0.0 ,默认带有Junit,但是不能自动生成单元测试,需要下载JunitGererator2.0插件 2.Settings -Plugins,下载 JunitGenerat ...

  2. Python的单元测试(二)

    title: Python的单元测试(二) date: 2015-03-04 19:08:20 categories: Python tags: [Python,单元测试] --- 在Python的单 ...

  3. Python的单元测试(一)

    title: Python的单元测试(一) author: 青南 date: 2015-02-27 22:50:47 categories: Python tags: [Python,单元测试] -- ...

  4. javascript单元测试框架mochajs详解

    关于单元测试的想法 对于一些比较重要的项目,每次更新代码之后总是要自己测好久,担心一旦上线出了问题影响的服务太多,此时就希望能有一个比较规范的测试流程.在github上看到牛逼的javascript开 ...

  5. 使用NUnit为游戏项目编写高质量单元测试的思考

    0x00 单元测试Pro & Con 最近尝试在我参与的游戏项目中引入TDD(测试驱动开发)的开发模式,因此单元测试便变得十分必要.这篇博客就来聊一聊这段时间的感悟和想法.由于游戏开发和传统软 ...

  6. 我这么玩Web Api(二):数据验证,全局数据验证与单元测试

    目录 一.模型状态 - ModelState 二.数据注解 - Data Annotations 三.自定义数据注解 四.全局数据验证 五.单元测试   一.模型状态 - ModelState 我理解 ...

  7. ABAP单元测试最佳实践

    本文包含了我在开发项目中经历过的实用的ABAP单元测试指导方针.我把它们安排成为问答的风格,欢迎任何人添加更多的Q&A's,以完成这个列表. 在我的项目中,只使用传统的ABAP report. ...

  8. python_单元测试unittest

    Python自带一个单元测试框架是unittest模块,用它来做单元测试,它里面封装好了一些校验返回的结果方法和一些用例执行前的初始化操作. 步骤1:首先引入unittest模块--import un ...

  9. .Net中的AOP系列之《单元测试切面》

    返回<.Net中的AOP>系列学习总目录 本篇目录 使用NUnit编写测试 编写和运行NUnit测试 切面的测试策略 Castle DynamicProxy测试 测试一个拦截器 注入依赖 ...

  10. React单元测试——十八般兵器齐上阵,环境构建篇

    一个完整.优秀的项目往往离不开单元测试的环节,就 github 上的主流前端项目而言,基本都有相应的单元测试模块. 就 React 的项目来说,一套完整的单元测试能在在后续迭代更新中回归错误时候给与警 ...

随机推荐

  1. linux服务器之间拷贝文件和文件夹

    传输文件用法:scp 本机文件目录 远程服务器用户名@服务器IP:/服务器目录 示例:

  2. linux开启mysql远程登录

    Mysql默认root用户只能本地访问,不能远程连接管理mysql数据库,Linux如何开启mysql远程连接?设置步骤如下:1.GRANT命令创建远程连接mysql授权用户itloggermysql ...

  3. NFC应用(二)读写器模式

    NFC第二种应用场境就是所谓的读写器模式.既然有卡,当然就会有读写器,这两种模式是配合在一起使用的.两个卡放一起不能通信,两个读写器模式的设备也不能通信. NFC读写器一般支持以下一种或多种协议:Mi ...

  4. C# Exception类

    一.异常类 1.在C#中所有的异常都是使用一个异常类型的示例对象表示的,这些异常类型都是继承自System.Exception类型,或者直接使用System.Exception类型的实例对象: 2.在 ...

  5. 中间容器 - JTabbedPane的用法的最简举例

    摘自并整理http://blog.csdn.net/liu_zhen_wei/article/details/6445345 JTabbedPane的用法的最简举例 package com.wst.b ...

  6. 【转】V4L2+swscale+X264+live555实现流媒体服务端

    写这边博客,一方面是因为自己在做项目的时候不太做笔记,怕以后自己忘记了.另一方面,是让正在寻求资料的同行少走一点弯路吧.不能说我这个方案怎么的好,至少是有一点参考价值的.这边博客需要一定基础才能看明白 ...

  7. iOS https认证 && SSL/TLS证书申请

    1.下面列出截止2016年底市面上常见的免费CA证书: 腾讯云SSL证书管理(赛门铁克TrustAsia DV SSL证书)阿里云云盾证书服务(赛门铁克DV SSL证书)百度云SSL证书服务Let's ...

  8. POJ3071:Football(概率DP)

    Description Consider a single-elimination football tournament involving 2n teams, denoted 1, 2, …, 2 ...

  9. ModelAndView解析

    查看spring的帮助文档得到下面信息: org.springframework.web.servlet Class ModelAndViewjava.lang.Object org.springfr ...

  10. RAID技术介绍和总结

    简介 RAID是一个我们经常能见到的名词.但却因为很少能在实际环境中体验,所以很难对其原理 能有很清楚的认识和掌握.本文将对RAID技术进行介绍和总结,以期能尽量阐明其概念. RAID全称为独立磁盘冗 ...