单元测试用例设计_第1页
单元测试用例设计_第2页
单元测试用例设计_第3页
单元测试用例设计_第4页
单元测试用例设计_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

一、概述.................................................1

二、基本概念.............................................1

2.1正面测试(PositiveTesting)..................................................................1

2.2负面测试(NegativeTesting)................................................................2

2.3分支测试..........................................2

2.4黑盒测试..........................................2

2.5白盒测试..........................................2

三、单元测试范围.........................................3

四、常见测试用例设计方法及举例...........................3

4.1用于语句覆盖的基路径法............................3

4.2用于MC/DC的真值表法............................9

4.3边界值法.........................................11

4.4等价类法.........................................12

4.5循环测试法.......................................17

4.6错误推测法.......................................18

五、相关注意事项........................................18

5.1独立性...........................................18

5.2尽量脱离被测代码的束缚...........................18

5.3面向对象的语言单元测试特点.......................18

5.4单元测试的命名标准...............................19

L单元测试的命名标准.............................19

2.单元测试中的变量命名规范......................19

3.断言和操作分离................................19

4.避免滥用setup和teardown............................................19

一、概述

单元测试(模块测试)是开发者编写的一小段代码,用于检验被

测代码的一个很小的、很明确的功能是否正确。通常而言,一个单元

测试是用于判断某个特定条件(或者场景)下某个特定函数的行为。

该文档从测试角度出发,去讨论如何设计单元测试的测试用例。

这里强调,单元测试用例的设计是进入实际编码之前的,测试用

例设计在前,更能体现出灵活性,如果已经编码完成再进行测试用例

的补充,这样很容易进入一个仅仅是测试了被测代码段功能的怪圈,

所以希望所有的单元测试工作,可以放在前面完成。同时单元测试用

例是一个不断完善的过程,前期设计好的用例,在代码已经实现完成

后,会发现覆盖的并不是很全面,有良好的习惯是需要将对应的测试

用例进行补充,而在提交测试后发现的重要的bug,也需要进行单元

测试用例的补充,使单元测试和各种测试方法相结合,实现测试质量

的充分保证。

二、基本概念

2.1正面测试(PositiveTesting)

测试被测对象的正确功能实现无误,即正常流程功能。往往需要

根据设计说明进行用例导出,严格按照设计说明编写即可,用例划分

注意等价类区分等方法。

例如:接口返回小于等于24个中文字的offer标题(这里标题控制不

1

会超过24个字)进行页面展示。

2.2负面测试(NegativeTesting)

测试被测对象的异常功能实现无误,多在异常流程,异常数据中

体现。该部分测试需要对被测对象进行错误发散,常依赖于边界值区

分等方法。

例如:接口返回25个中文字的offer标题进行页面展示。

2.3分支测试

使用流程图,明确可能出现的每条分支,制造响应的数据进行覆

盖,实现对被测对象的测试。这个过程对于分支可以进行响应的简化,

可以穿插等价类等方法去除同类分支。

例如:实现。ffer发布的功能,分别会出现发布普通产品,代理加盟,

求购,供应等分支,测试。ffer提交模块的时候,需要区分这么多重

类型的数据,那么假设对于全部供应类型的offer,实现上都是一样

的,就可以进行等价类划分,区分供应和求购即可。

2.4黑盒测试

不关心被测对象内部,将其当做一个黑盒,仅仅关注对该模块的

输入区分和输出结果校验。

2.5白盒测试

2

将被测对象的每个实现都充分了解,根据内部实现进行用例设

计■,需要保证每个独立路径都完成用例覆盖,而常规的对每个独立路

径进行真假验证。

三、单元测试范围

单元测试范围的重点包括两个方面:1.测试代码实现的功能,这

个可以通过需求文档进行整理,然后调整每个功能点的颗粒度,尽量

可以和开发实现的被测单元进行对应,入口文档包括需求文档、设计

文档;2.外部接口和底层实现。

四、常见测试用例设计方法及举例

4.1用于语句覆盖的基路径法

基路径法保证设计出的测试用例,使程序的每一个可执行语句至

少执行一次,即实现语句覆盖。基路径法是理论与应用脱节的典型,

基本上没有应用价值,读者稍作了解即可,不必理解和掌握。

基路径法步骤如下:

1)画出程序的控制流图

控制流图是描述程序控制流的一种图示方法,主要由结点和边构

成,边代表控制流的方向,节点代表控制流的汇聚处,边和结点圈定

的空间叫做区域,下面是控制流图的基本元素:

3

依序结构•,IF选择结构”While罐环结构,CASE多分支结构•,

Until循环结构.

以下代码:

voidSort(intiRecordNum,intiType)

{

intx=0;

inty=0;

while(iRecordNum—>0)

{

if(0==iType)

{

x=y+2;

break;

4

}

elseif(1==iType)

x=y+10;

eIse

x=y+20;

}

可以画出以下控制流图:

5

2)计算程序环路复杂度

环路复杂度V(G)可用以下3种方法求得:

(1)环路复杂度等于控制流图中的区域数;

上图中,有4个区域,V(G)=4。

(2)设E为控制流图的边数,N为结点数,则环路复杂度为E—N+

2;

上图中,V(G)=10(边)一8(结点)+2=4。

(3)设P为控制流图中的判定结点数,环路复杂度为P+1。

6

上图中:V(G)=3(判定结点)+1=4。

环路复杂度是独立路径数的上界,也就是需要的测试用例数的上界。

3)导出基本路径集

基本路径数等于V(G)。根据上面的计算方法,可得出需要的基

本路径数为4。路径就是从程序的入口到出口的可能路线,基本路径

要求每条路径至少包含一条新的边,直到所有的边都被包含。需要提

醒的是:基路径法和路径覆盖是两回事,用于设计用例的基路径数一

般小于全部路径数,即基本路径集不是惟一的。基路径法完成的是语

句覆盖,而不是路径覆盖。下面选择四条基本路径:

路径1:1-11

路径2:1-2-3-4-5-1-11

路径3:1-2-3-6-8-9-10-1-11

路径4:1-2-3-6-7-9-10-1-11

4)设计用例

根据上面的路径,可以设计出以下用例:

7

路径1:1-11

用例1:iRecordNum=0

路径2:1-2-3-4-5-1-11

用例2:iRecordNum=1,iType=0

路径3:1-2-3-6-8-9-10-1-11

用例3:iRecordNum=1,iType=1

路径4:1-2-3-6-7-9-10-1-11

用例4:iRecordNum=1,iType=2

从上述步骤可以看出,基路径法工作量巨大,如果用于五十行左

右的函数,将耗费大量的时间,而五十行代码的函数实在是太普通了。

这种成本巨高的方法,其测试效果如何呢?测试效果完全与成本不匹

配,首先,基路径法完成的只是代码覆盖,这是最低级别的覆盖,其

次,整个设计过程都是依据已经存在的代码来进行的,没有考虑程序

的设计功能,是典型的“跟着代码走”,不足是显而易见的。综上所述,

基路径法没有实际应用价值。

8

4.2用于MC/DC的真值表法

设计用于MC/DC的用例,可以先将条件值的所有可能组合列出

表格,然后从中选择用例,称为真值表法。例如判定A||(B&&C),

条件组合如下表:

ABC判定结果

组合1TTTT

组合2TTFT

组合3TFTT

组合4TFFT

组合5FTTT

组合6FTFF

组合7FFTF

组合8FFFF

为了使A独立影响判定结果,选择B和C相同,判定结果相反,且

A相反的组合:组合2和6;

为了使B独立影响判定结果,选择A和C相同,判定结果相反,且

B相反的组合:组合5和7;

为了使C独立影响判定结果,选择A和B相同,判定结果相反,且

C相反的组合:组合5和6。

9

因此,组合2、5、6、7符合MC/DC要求。符合MC/DC要求的用

例集不是惟一的。

为了提高效率,可以使用工具来生成真值表和找出符合要求的组合,

有些商业工具具有这种功能。自行开发难度也不大,下面提出开发

MC/DC用例设计小工具的思路,有兴趣的读者可以尝试一下:

1)用一个简单的词法和语法分析器解析判定表达式,计算条件数量;

2)生成真值表;

3)用一个逻辑表达式计算器,针对每个条件C,扫描真值表,找出

符合以下要求的组合:除条件C外,其他条件取值相同;将条件C

的真值和假值分别代入判定表达式,判定的计算结果相反。

4)针对找出的组合,设计两个用例,条件C分别取真和假。

需要注意的是,判定中可能存在完全相同的条件,例如:

(A==011B==1)&&C==211(A==0&&D==3)

针对A==0设计MC/DC用例时,前一个A==0取反,后一个A==0

也会跟着取反,如果后一个A==0视为其他条件,则不能实现

MC/DC覆盖,因此,计算判定值时,两个A==0应视为同一个条

件。

10

4.3边界值法

边界值法假定错误最有可能出现在区间之间的边界,一般对边界

值本身,及边界值的两边都需设计测试用例。

如下函数:

〃参数age表示年龄

intfunc(intage)

{

intret=0;

〃…dosomething

returnret;

}

参数age表示一个人的年龄,假设有效的取值范围是0-200,那么,

用边界值法可以得出以下用例(省略输出):

用例1:age=-1;

用例2:age=0;

11

用例3:age=1;

用例4:age=199;

用例5:age=200;

用例6:age=201;

通常,程序对输入还会分段处理,例如,年龄在10以下,为儿童,

需要特别照顾;年龄在60岁以上,为退休老人,不能安排工作,那

么,10和60是内部边界,也要设计测试用例:

用例7:age=9;

用例8:age=10;

用例9:age=11;

用例10:age=59;

用例11:age=60;

用例12:age=61;

边界值法需要了解数据所代表的实际意义,此外对于枚举类型等非标

量数据不适用。边界值法对于复杂的软件项目来说,适用范围有限。

4.4等价类法

12

先从代码编写的思路说起。程序员编写一个函数的代码,会如何

做呢?

首先,了解代码功能。程序的功能是什么?无非就是:有哪些输

入?执行什么操作或计算?产生什么输出?

然后,将功能细化,形成一个或多个功能点。一个功能点就是一

类输入及其处理。什么叫"一类〃输入?程序可能有无数输入,但代码

并不需要用无数个判定来对每个输入分别做处理,只需将输入分类,

需要做相同处理的输入归于一类,这就是"等价类〃。从编程角度来说,

"等价类''是指计算或操作过程的"等价",一个等价类就是处理过程完

全相同的输入的集合。程序中通常用判定来识别分类,一个判定就是

一次分类,嵌套的判定则会造成分类数量的翻番。

所以,函数代码编写的核心思维就是等价类划分和处理。一个函

数要完全正确,关键是等价类的划分要正确完整,且每个等价类的处

理正确。

举个例子,现在要编写一个函数,将字符串左边的空格删除。函

数原形如下:

char*strtrml(char*str);

功能:

将str左边空格删除,并返回str本身。

13

功能点:

1.左边有空格:删除;(正常输入)

2.左边无空格:不作处理;(正常输入)

3.全部是空格:全部删除;(正常输入)

4.空串:不作处理;(边界输入)

5.空指针:直接返回。(非法输入)

不一定需要针对每个功能点分别写代码,因为程序中的if、for、

while等语句本身具有“如果不符合条件就跳过〃的含义,所以很多功

能点是可以共用代码的,例如,前4个功能点只需要相同的代码,不

过,编程时对功能点的考虑还是要全面。

既然函数没有错误的关键是等价类划分正确完整且处理正确,那

么测试时,只要把输入的等价类都列出来,并设定正确的预期输出,

进行测试就行了。

这就是通常说的“等价类''法,从测试角度来说的“等价”,是指测

试效果上的等价,即同类中一个数据测试通过,可以肯定其他数据也

会测试通过。

14

用例设计的首要工作是设定输入。输入有哪些呢?要从正常输

入、边界输入、非法输入三方面考虑,每方面进一步划分形成等价类,

即要考虑:有哪些正常输入?有哪些边界输入?有哪些非法输入?

多个输入时,例如有多个参数,首先把各个参数的等价类列出来,然

后要考虑参数之间是否存在特殊的组合关系。例如下面的函数:

//计算某年某月某日是星期几,参数分别表示年月日

intDate(intyear,intmonth,intday);

用例如下表(假设year的有效范围是1-9999):

输入正常值边界值非法值组合

Year2000(闰年)10闰年和非闰年要保证都

和2月组合;

2009(非闰年)999910000

2月要和28、29、30

month2(短月)10

日组合;

3(大月)

1213小月要和30、31日组

4(小月)

合;

Day10(普通)10

大月要和31、32日组合

28(非闰年二

3132

月)

29(闰年二月)

15

30(小月)

用例的输出是比较容易被轻视的工作,但是,没有充分且正确的

预期输出,用例基本上没有意义,就像医生要求病人做一大堆检查,

却不看检查结果一样。预期输出要根据程序的设计功能确定正确的

值。一个用例的预期输出可能有多个。

等价类法是与程序的基本特性”对数据分类处理''相匹配的方法。

对于一个函数来说,如果对数据的分类正确且完整,每一个分类处理

正确,那么,程序就没有问题。同样,测试时,只要依据设计功能,

找出所有等价类,那么,用例就是完整的。所以,用例的完整性,本

质上是指等价类是否划分正确且完整,每一类的正确输出是否均依据

设计功能正确设定。

使用了等价类法后,是否需要使用其他方法呢?

等价类法从“有哪些正常输入?有哪些边界输入?有哪些非法输

入?〃三个方面来考虑等价类,因此,边界值法是等价类法的一部分。

常见的用例设计方法中还有正交法和错误推测法。正交法考虑数

据的组合,实际上,如果程序对输入数据的组合需要判断处理,也是

一种等价类划分,但正交法会产生大量的多余组合,且可能缺少必要

的组合,因此不推荐采用正交法,应该根据数据的实际意义自行组合。

16

单独从错误推测角度去设计用例未免太不可靠,但错误推测法可以作

为检查等价类是否完整的一种思路,即用等价类法设计用例后,可以

考虑哪些输入比较容易产生错误,以检查是否遗漏,这只是一种检查

思路,也包含在等价类法之中。总之,用例设计只需使用等价类法,

但可以从多种角度检查等价类的完整性。

4.5循环测试法

在程序中多循环判断是,我们一样需要重点关注,根据循环的重

量级进行。

例如一个简单循环判断:

如下图4-5,有如下几个分支需要覆盖:

1、跳过整个循环:不进入循环流程

2、仅有一次进入循环:需要进行数据构造,能够让循环运行一

3、n次进入循环(n为循环的最大次数)

不难看出,通过上述分支的覆盖,就可以验证循环的功能以及循

环设置的边界是否生效,不会出现循环没有控制好,导致实际使用的

时候会多进行一次或者少进行一次循环的情况。

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论