C++之单元测试
以前编写程序从没有做过单元测试的工作,所以在后期会花很多时间去纠错,这也就是软件工程中的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++之单元测试的更多相关文章
- Intellij idea添加单元测试工具
1.idea 版本是14.0.0 ,默认带有Junit,但是不能自动生成单元测试,需要下载JunitGererator2.0插件 2.Settings -Plugins,下载 JunitGenerat ...
- Python的单元测试(二)
title: Python的单元测试(二) date: 2015-03-04 19:08:20 categories: Python tags: [Python,单元测试] --- 在Python的单 ...
- Python的单元测试(一)
title: Python的单元测试(一) author: 青南 date: 2015-02-27 22:50:47 categories: Python tags: [Python,单元测试] -- ...
- javascript单元测试框架mochajs详解
关于单元测试的想法 对于一些比较重要的项目,每次更新代码之后总是要自己测好久,担心一旦上线出了问题影响的服务太多,此时就希望能有一个比较规范的测试流程.在github上看到牛逼的javascript开 ...
- 使用NUnit为游戏项目编写高质量单元测试的思考
0x00 单元测试Pro & Con 最近尝试在我参与的游戏项目中引入TDD(测试驱动开发)的开发模式,因此单元测试便变得十分必要.这篇博客就来聊一聊这段时间的感悟和想法.由于游戏开发和传统软 ...
- 我这么玩Web Api(二):数据验证,全局数据验证与单元测试
目录 一.模型状态 - ModelState 二.数据注解 - Data Annotations 三.自定义数据注解 四.全局数据验证 五.单元测试 一.模型状态 - ModelState 我理解 ...
- ABAP单元测试最佳实践
本文包含了我在开发项目中经历过的实用的ABAP单元测试指导方针.我把它们安排成为问答的风格,欢迎任何人添加更多的Q&A's,以完成这个列表. 在我的项目中,只使用传统的ABAP report. ...
- python_单元测试unittest
Python自带一个单元测试框架是unittest模块,用它来做单元测试,它里面封装好了一些校验返回的结果方法和一些用例执行前的初始化操作. 步骤1:首先引入unittest模块--import un ...
- .Net中的AOP系列之《单元测试切面》
返回<.Net中的AOP>系列学习总目录 本篇目录 使用NUnit编写测试 编写和运行NUnit测试 切面的测试策略 Castle DynamicProxy测试 测试一个拦截器 注入依赖 ...
- React单元测试——十八般兵器齐上阵,环境构建篇
一个完整.优秀的项目往往离不开单元测试的环节,就 github 上的主流前端项目而言,基本都有相应的单元测试模块. 就 React 的项目来说,一套完整的单元测试能在在后续迭代更新中回归错误时候给与警 ...
随机推荐
- cxf2.7.10 与 spring3.0.5集成
开发环境: NetBeans7.4 Tomcat 6.0.32 一 服务端: 1:新建JavaWeb工程 cxfspring-server,导入jar包如下图所示: 2:在web.xml文件中添加如下 ...
- Delphi泛型评测(30篇)
http://www.cnblogs.com/jxgxy/category/216671.html
- 查看mysql 服务器上的连接进程
SHOW PROCESSLIST #展示全部的连接进程 select * from information_schema.processlist where db='qwuliu' #可以进行筛选查 ...
- Android 打开URL
打开链接 Intent it = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.baidu.com")); it.set ...
- awk 处理
find . -type f | awk '{print $NF}' | grep pdf$ |grep -v preview | while read A; do ls -ltr $A| awk ' ...
- xen vhd操作工具source code研读
推出最新的VHD操作工具VHD-UTIL 实现源码,超强,Ruiy只为学习高手的设计思路
- 文件系统、mkdir、touch、nano、cp笔记
文件系统:rootfs: 根文件系统 FHS:Linux发行版目录层级遵循协议 /boot: 系统启动相关的文件,如内核.initrd,以及grub(bootloader)引导加载器/dev: 设备文 ...
- Linux —— Shell编程之变量赋值和引用
Linux的shell编程是一种非常成熟的编程语言,它支持各种类型的变量.有三种主要的变量类型:环境变量.内部变量和用户变量. 环境变量(environment variable)是系统环境的一部分, ...
- CSS3初步
一.CSS与CSS3的区别 非常简单,CSS代表"Casading Style Sheets",就是样式表,是一种替代并为网站添加样式的标记性语言.现在所使用的CSS基本是在199 ...
- 编解码学习笔记(十):Ogg系列
Ogg是一个自由且开放标准的容器格式,由Xiph.Org 基金会所维护.Ogg格式并不受到软件专利的限制,并设计用于有效率地串流媒体和处理高质量的数字多媒体. Ogg意指一种文件格式,能够纳入各式各样 ...