作者:张元礼
http://blog.csdn.net/vincetest
1.1 一些错误的认识
在实际的测试>单元测试过程中总会有一些错误的认识左右着我们,使之成为测试>单元测试最大的障碍,在此将其一一分析如下:
【文章来源:张元礼的博客
http://blog.csdn.net/vincetest
】
-
它太浪费时间了,现在要赶进度,时间上根本不允许,或者随便做做应付领导。
-
我是一个很棒的程序员,我写的代码肯定是没有问题的。
-
它仅仅是证明这些代码做了什么。
1.2 测试的重要性
综上所述,测试>单元测试是构筑产品质量的基石,我们不要因为节约测试>单元测试的时间不做测试>单元测试或随便做而让我们在后期浪费太多的不值得的时间,我们也不愿意因为由于节约那些时间导致开发出来的整个产品失败或重来!
1.3 具有的优点
1. 它是一种验证行为。
程序中的每一项功能都是测试来验证它的正确性,为以后的开发提供支缓。就算是开发后期,我们也可以轻松的增加功能或更改程序结构,而不用担心这个过程中会破坏重要的东西。而且它为代码的重构提供了保障,这样,我们就可以更自由的对程序进行改进。
2.它是一种设计行为。
编写测试>单元测试将使我们从调用者观察、思考,特别是先写测试(test-first),迫使我们把程序设计成易于调用和可测试的,即迫使我们解除软件中的耦合。另外还可以使编码人员在编码时产生预测试,将程序的缺陷降低到最小。
【文章来源:张元礼的博客
http://blog.csdn.net/vincetest
】
3.它是一种编写文档的行为。
4.它具有回归性。
2.1 基本概念
1. 测试>单元测试:测试>单元测试又称模块测试,属于白盒测试,是最小单位的测试。模块分为程序模块和功能模块。功能模块指实现了一个完整功能的模块(单元),一个完整的程序单元具备输入、加工和输出三个环节。而且每个程序单元都应该有正规的规格说明,使之对其输入、加工和输出的关系做出名明确的描述。
3.测试桩:代替被测模块调用的子模块的实体,该实体一般为桩函数。
5.覆盖率:代码的覆盖程度,一种度量方式。针对代码的测试覆盖率有许多种度量方式,定义如下:
-
语句覆盖(StatementCoverage):也称为行覆盖(lin EC),段覆盖(segmentcoverage)和基本块覆盖(b AS)。它度量每一个可执行语句是否被执行到了。icblockcoverageoverage
-
判定覆盖(DecisionCoverage):也被称为分支覆盖(branchcoverage),所有边界覆盖(all-edgescoverage),基本路径覆盖(basispathcoverage),判定路径覆盖(decision-decision-path或DDPtesting)。它度量是否每个B OO型的表达式取值true和false在控制结构中都被测试到了。L
-
条件覆盖(Con DI):它独立的度量每一个子表达式,报告每一个子表达式的结果的true或false。这个度量和判定覆盖(decisioncoverage)相似,但是对控制流更敏感。不过,完全的条件覆盖并不能保证完全的判定覆盖。tionCoverage
-
循环覆盖(L OOP):这个度量报告你是否执行了每个循环体零次、只有一次还是多余一次(连续地)。对于do-while循环,循环覆盖报告你是否执行了每个循环体只有一次还是多余一次(连续地)。这个度量的有价值的方面是确定是否对于while循环和for循环执行了多于一次,这个信息在其它的覆盖率报告中是没有的。 【文章来源:张元礼的博客 http://blog.csdn.net/vincetest 】
2.2 测试的内容
测试>单元测试的对象是软件设计的最小单位——模块或函数,测试>单元测试的依据是详细设描述。测试者要根据详细设计说明书和源程序清单,了解模块的I/O条件和模块的逻辑结构。主要采用白盒测试的测试用例,辅之以黑盒测试的测试用例,使之对任何合理和不合理的输入都能鉴别和响应。要求对所有的局部和全局的数据结构、外部接口和程序代码的关键部分进行桌面检查和代码审查。在测试>单元测试中,需要对下面5个方面的内容进行测试,也是构造测试用例的基础。
-
调用所测模块时的输入参数与模块的形式参数在个数、属性、顺序上是否匹配;
-
所测模块调用子模块时,它输入个子模块的参数与子模块的形式参数在个数、属性、顺序上是否匹配;
-
是否修改了只做输入用的形式参数;
-
输出给标准函数的参数在个数、属性、顺序上是否匹配;
-
全局变量的定义在各模块中是否一致;
-
限制是否通过形式参数来传送。
-
检查不正确或不一致的数据类型说明;
-
使用尚未赋值或尚未初始化的变量;
-
错误的初始值或错误的默认值;
-
变量名拼写错误或书写错误;
-
不一致的数据类型。 【文章来源:张元礼的博客 http://blog.csdn.net/vincetest 】
-
常见的不正确的计算有:
Ø 运算的优先次序不正确或误解了运算的优先次序;
Ø 运算的方式错误(运算的对象彼此在类型上不相容);
Ø 算法错误;
Ø 初始化不正确;
Ø 运算精度不够;
Ø 表达式的符号表示不正确等。
-
常见的比较和控制流错误有:
Ø 不同数据类型的比较;
Ø 不正确的逻辑运算符或优先次序;
Ø 因浮点运算精度问题而造成的两值比较不等;
Ø 关系表达式中不正确的变量和比较符;
Ø “差1错”,即不正确地多循环或少循环一次;
Ø 错误的或不可能的循环终止条件;
Ø 当遇到发散的迭代时不能终止循环;
Ø 不适当地修改了循环变量等。
4) 错误处理测试:比较完善的模块设计要求能预见出错的条件,并设置适当的出错处理对策,以便在程序出错时,能对出错程序重新做安排,保证其逻辑上的正确性。这种出错处理也是模块功能的一部分。表明出错处理模块有错误或缺陷的情况有:
-
出错的描述难以理解;
-
出错的描述不足以对错误定位和确定出错的原因;
-
显示的错误与实际的错误不符;
-
对错误条件的处理不正确;
-
在对错误进行处理之前,错误条件已经引起系统的干预;
-
如果出错情况不予考虑,那么检查恢复正常后模块可否正常工作。
-
在n次循环的第0次、1次、n次是否有错误;
-
运算或判断中取最大最小值时是否有错误;
-
数据流、控制流中刚好等于、大于、小于确定的比较值时是否出现错误。
2.3 测试的环境构成
何时进行测试>单元测试?测试>单元测试在编码阶段进行。在源程序代码编制完成、经过评审和验证、确认没有语法错误之后,就可以开始进行测试>单元测试的测试用例设计。要利用软件设计文档,设计可以验证程序功能、找出程序错误的多个测试用例。
【文章来源:张元礼的博客
http://blog.csdn.net/vincetest
】
-
桩模块(Stub):用来代替所测模块调用的子模块。
3 测试方法与过程
3.1 用例设计
-
用例运行前置条件
-
被测模块/单元所需环境(全局变量赋值或初始化实体)
-
启动测试驱动
-
设置桩
-
调用被测模块
-
设置预期输出条件判断
-
恢复环境(包括清除桩)
2.测试用例的设计原则
-
一个好的测试用例在于能够发现至今没有发现的错误;
-
在测试用例设计时,应当包含合理的输入条件和不合理的输入条件;
-
为系统运行起来而设计测试用例;
-
为满足特殊需求而设计测试用例;
-
为代码覆盖而设计测试用例;
3.用例设计方法
1) 规范(规格)导出发
2) 等价类划分法
3) 边界值分析法
4) 状态转移测试法
5) 分支测试法
6) 条件测试法
8) 内部边界值测试法
9) 错误猜测法
4. 特定的用例测试设计
1)声明测试:检查模块中的所有变量是否被声明。经验表明,大量重要的错误都是由于变量没有被声明或没有被正确的声明而引起的。
基本路径测试:由于实际中,一个模块中的路径可能非常多,由于时间和资源有限,不可能一一测试到。这就需要把测试所有可能路径的目标减少到测试足够多的路径,以获得对模块的信心。要测试的最小路径集就是基本测试路径集。基本测试路径集要保证:
-
每个确定语句的每一个方向要测试到;
-
每条语句最少执行一次。
3)循环测试:重点检查循环的条件-判断部分以及边界条件。测试循环是一种特殊的路径测试,因为循环比其他语句都复杂一些。循环中错误的发生机会比其他代码构成部分多。因此,对于任何给定的循环测试应该包括测试下面每一条件的测试用例:
-
循环不执行;
-
执行一次循环;
-
执行两次循环;
-
反映执行典型的循环的执行次数;
-
如果有最大循环次数,最大循环次数减1;
-
最大循环次数;
-
大于最大循环次数。
对于增量和减量不是1的FOR语句,要特别注意,因为程序员习惯于增量1。
-
把外循环设置为最小值,并运行内循环所有可能的情况;
-
把内循环设置为最小值,并运行外循环所有可能的情况;
-
把所有的循环变量都设置为最小值运行;
-
把所有的循环变量都设置为最大值运行;
-
把外循环设置为最大值,并运行内循环所有可能的情况;
-
把内循环设置为最大值,并运行外循环所有可能的情况;
5) 边界值测试:指程序内部边界测试。检查确定代码在任何边界情况下都不会出差错。重点检查小于、等于和大于边界条件的情况。边界值测试是指专门设计用来测试当条件语句中引用的值处在边界或边界附近时系统反映的测试。被测试语句的最好的例子就是“IF-THEN…ELSE-ENDIF”部分。这样语句的例子如:
【文章来源:张元礼的博客
http://blog.csdn.net/vincetest
】
IF a <= 123 THEN
b = 1
ELSE IF a >= 123 THEN
b = 2
ELSE b = 3
END IF
上面例子中的边界值测试用例应该至少包括a的以下值:122,123,124。当a=123时,b=1还是2。(找出逻辑判断的矛盾)
6)接口测试:检查模块的数据流(输入、输出)是否正确。检查输入的参数和声明的自变量的个数,数据类型和输入顺序是否一致。检查全局变量是否被正确的定义和使用等。
7)确认测试:是否接受有效输入数据(操作),拒绝无效数据(操作)。
8)事务测试:输入->输出,错误处理。
3.2 用例执行
一般来说,做测试>单元测试均采用的是商用的测试工具或自行开发的测试工具,用例的编写都是在测试工具上完成,测试用例都是一些测试脚本,都以文件的方式来保存,故其用例的执行过程主要是由测试工具根据所编写的具体的测试用例脚本来完成,这样对于用例的管理和执行也非常灵活。
在用例的执行过程中务必注意如下事项:
-
程序的执行过程―――便于构造发散用例
-
不要放过任何细节―――这种细节可能就是问题
在测试的过程中为了提高测试效率和效果,不断的减少冗余劳动,也为后期的回归测试和测试管理带来很大的方便,不至于感到测试很混乱无序。因此我们要对测试用例和测试执行进行不断的优化,以测试策略为指导方针进行测试。
【文章来源:张元礼的博客
http://blog.csdn.net/vincetest
】
3、测试策略
-
哪些是重点模块?
-
哪些程序是最复杂、最容易出错的?
-
哪些程序是相对独立,应当提前测试的?
-
哪些程序最容易扩散错误?
-
哪些程序是开发者最没有信心的?
3.4 测试评估
2)代码覆盖率评估,主要是根据代码覆盖率工具提供的语句覆盖情况报告,检查是否达到方案中的要求,公司要求语句覆盖达到100%。但很多情况下,第一轮测试用例执行完后是很难达到的,这时在评估过程中要对覆盖率进行分析,主要从以下方面来考虑:
-
不可能的路径或条件
-
不可达的或冗余的代码
-
不充分的测试用例
3) 从覆盖的角度看,测试应该覆盖:
-
功能覆盖
-
输入域覆盖
-
输出域覆盖
-
函数交互覆盖
-
代码执行覆盖
3.5 测试过程
1.测试过程中各种人员的作用
-
系统分析设计人员
-
软件开发人员
-
软件测试人员
-
配置管理人员
-
质量保证(QA)人员
-
《需求跟踪说明书》或需求跟踪记录
-
代码静态检查记录
-
《正规检视报告》
-
问题记录
-
问题跟踪和解决记录
-
软件代码开发版本
3.6 测试实施
2) 根据计划和方案及相关输入文档编写测试用例
3) 搭建测试环境
4) 执行测试
5) 记录和跟踪问题
6) 编写测试报告和总结报告
4 常用测试工具介绍
1. VcTester
1) 简介
VcTester是与VC(注:Visual C++及Visual Studio开发套件是微软发布的产品)配套使用的新一代测试>单元测试工具,分共享版与商用版两大系列,其主要功能包括:脚本化测试驱动(包括修改变量与调用函数)、脚本桩、支持持续集成测试、测试覆盖率统计(仅商用版本)、生成测试报告(仅商用版本)、测试消息编辑器(仅商用版本)等。
2) 功能特性
3) 价格
共享版免费
4) 相关网站
www.ezTester.com
2. C++Test
1) 简介
C++Test是一个功能强大的自动化C/C++单元级测试工具,可以自动测试任何C/C++函数、类,自动生成测试用例、测试驱动函数或桩函数,在自动化的环境下极其容易快速的将单元级的测试覆盖率达到100%。
2) 功能特性
【文章来源:张元礼的博客
http://blog.csdn.net/vincetest
】
-
即时测试类/函数
-
支持极端编程模式下的代码测试
-
自动建立类/函数的测试驱动程序和桩调用
-
自动建立和执行类/函数的测试用例
-
提供快速加入和执行说明和功能性测试的框架
-
执行自动回归测试
-
执行部件测试(COM)
3) 价格
不详
【文章来源:张元礼的博客
http://blog.csdn.net/vincetest
】
4) 相关网站
http://www.parasoft.com
欢迎转载此文,转载时请注明文章来源:张元礼的博客 http://blog.csdn.net/vincetest
欢的网站:
新浪网
Google新闻
搜狐新闻
雅虎
天极
CSDN新闻
CSDN博客
B周刊
博客中心
DoNews博客
SourceForge
ShareIt
无忧测试
VC在线
共创联盟
华军软件园