第06章软件实现_第1页
第06章软件实现_第2页
第06章软件实现_第3页
第06章软件实现_第4页
第06章软件实现_第5页
已阅读5页,还剩137页未读 继续免费阅读

下载本文档

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

文档简介

软件工程

SoftwareEngineering

主讲教师:宋涛电子邮箱:songme2000@163.com手机始i=1,j=0,k=0,m=0输入学生人数Ni≤N?输出“奖100元比例:”,j/N*100,“%”输出“奖50元比例:”,k/N*100,“%”输出“奖20元比例:”,m/N*100,“%”输入名单、成绩成绩>90?j++,i++输出名单成绩奖励100元结束成绩>80?k++,i++输出名单成绩奖励50元成绩>60?m++,i++输出名单成绩奖励20元i++NNYYYYNN3/84:第6章软件实现

实现=<编码,测试>

编码:软件设计程序程序的质量主要取决于软件设计的质量。程序设计语言的特点和编码风格也会对程序的可靠性、可读性、可测试性和可维护性产生深远的影响。所谓编码就是把软件设计翻译成计算机可以理解的形式——用某种程序设计语言书写的程序。在进行软件分析、设计的过程中,难免有各种各样的错误,软件开发过程始终需要有质量保证活动。软件测试是主要的质量保证活动之一。测试的目的就是在软件投入生产性运行之前,尽可能多地发现软件中的错误。软件测试在软件生命周期中横跨两个阶段。通常在编写出每个模块之后就对它做必要的测试(称为单元测试),模块的编写者和测试者是同一个人,编码和单元测试属于软件生命周期的同一个阶段。在这个阶段结束之后,对软件系统还应该进行各种综合测试,这是软件生命周期中的另一个独立的阶段,通常由专门的测试人员承担这项工作。仅就测试而言,它的目标是发现软件中的错误,但是,发现错误并不是我们的最终目的。软件工程的根本目标是开发出高质量的完全符合用户需要的软件,因此,通过测试发现错误之后还必须诊断并改正错误,这就是调试的目的。调试是测试阶段最困难的工作。6.1结构化程序设计6.2选择程序设计语言6.3程序设计风格6.4程序设计质量的评价6.5程序设计文档6.6软件测试的目标和原则6.7软件测试的方法6.8软件测试的步骤6.9设计测试方案6.10软件调试、验证与确认6.1结构化程序设计作为软件工程过程的一个阶段,编码是设计的自然结果,因此,程序的质量主要取决于软件设计的质量。但是,所选用的程序设计语言的特点和编码风格也会对程序的可靠性、可读性、可测试性和可维护性产生深远的影响。什么是结构化程序设计?结构化程序设计(StructuredProgram)是由基本的控制结构构造而成的程序。每个控制结构只有一个入口点和一个出口点。控制结构集包括指令序列、指令或指令序列的条件选择,以及一个指令或指令序列的重复执行。结构化程序设计严格地使用结构化程序构造软件,并强调模块只采用顺序、选择、循环三种基本控制结构。例:打印A,B,C三个数中最小者的程序程序1:

if(A<B)goto120;

if(B<C)goto110;100write(C);

goto140;110write(B);

goto140;120if(A<C)goto130;

goto100;130write(A);140end程序2:

if(A<B)and(A<C)then

write(A) else

if(A>=B)and(B<C)then

write(B) else

write(C)

endif

endif6.2选择程序设计语言做为软件工程过程的一个阶段,程序编码是设计的继续。程序设计语言的特性会深刻地影响软件的质量和可维护性。为了保证程序编码的质量,程序员必须深刻理解、熟练掌握并正确地运用程序设计语言的特性。此外,还要求源程序具有良好的结构性和良好的程序设计风格。目前应用较多的程序设计语言主要分为面向机器语言和高级程序设计语言两大类。面向机器语言面向机器语言包括机器语言和汇编语言。他们都依赖于计算机硬件结构,指令系统因机器而异,难学难用。缺点:编程效率低、容易出错、维护困难。优点:易于实现系统接口,执行效率高。选择面向机器语言的情况:软件系统对程序执行时间和使用空间都有严格限制。系统硬件是特殊的微处理机,不能使用高级语言。大型系统中某一部分,其执行时间非常关键,或直接依赖于硬件,这部分用汇编语言编写。高级程序设计语言高级程序设计语言使用的概念和符号与人们通常使用的概念和符号比较接近,一般不依赖于计算机,通用性强。高级语言选用的实用标准:(1)项目的应用领域(2)软件开发环境(3)根据系统用户的要求来选择(4)软件开发人员的知识6.3程序设计风格程序实际上也是一种供人阅读的文章,有一个文章的风格问题。程序设计风格指编写程序时的特点、习惯和编辑思路等。应该使程序具有良好的风格。源程序代码的逻辑简明清晰、易读易懂是好程序的一个重要标准,为了做到这一点,应该遵循下述规则。

源程序文档编写规则数据说明语句构造要简单直接输入/输出语句 程序效率

1.程序内部的文档 所谓程序内部的文档包括恰当的标识符、适当的注解和程序的视觉组织等等。符号名的命名符号名即标识符,包括模块名、变量名、常量名、标号名、子程序名、数据区名以及缓冲区名等。这些名字应能反映它所代表的实际东西,应有一定实际意义。例如,表示次数的量用Times,表示总量的用Total,表示平均值的用Average,表示和的量用Sum等。程序的注释

夹在程序中的注释是程序员与日后的程序读者之间通信的重要手段。注释决不是可有可无的。一些正规的程序文本中,注释行的数量占到整个源程序的1/3到1/2,甚至更多。通常在每个模块开始处用注解简述模块的功能、主要算法、接口特点、调用方法及开发简史等。注释内容要正确,要对重要数据的含义、用途、限制以及约束进行注解。注释分为序言性注释和功能性注释。

序言性注释,通常置于每个程序模块的开头部分,它应当给出程序的整体说明,对于理解程序本身具有引导作用。有些软件开发部门对序言性注释做了明确而严格的规定,要求程序编制者逐项列出;功能性注释嵌在源程序体中,用以描述其后的语句或程序段是在做什么工作,或是执行了下面的语句会怎么样。而不要解释下面怎么做。视觉组织空格、空行和移行恰当地利用空格,可以突出运算的优先性,避免发生运算的错误。例如,将表达式

(A<-17)ANDNOT(B<=49)ORC

写成

(A<-17)ANDNOT(B<=49)ORC自然的程序段之间可用空行隔开;对于选择语句和循环语句,把其中的程序段语句向右做阶梯式移行。使程序的逻辑结构更加清晰。1.数据说明的次序应当规范化2.说明语句中变量安排有序化3.使用注释说明复杂数据结构4.变量说明不要遗漏,变量的类型、长度、存储及初始化要正确2.数据说明虽然在设计期间已经确定了数据结构的组织和复杂程度,然而数据说明的风格却是在写程序时确定的。为了使数据更容易理解和维护,有一些比较简单的原则应该遵循。3.语句构造要简单直接 构造语句时应该遵循的原则是,每个语句都应该简单而直接,不能为了提高效率而使程序变得过分复杂。1.在一行内只写一条语句2.程序编写首先应当考虑清晰性3.程序要能直截了当地说明程序员的用意。4.除非对效率有特殊的要求,程序编写要做到清晰第一,效率第二。5.首先要保证程序正确,然后才要求提高速度。6.尽可能使用库函数7.避免不必要的转移。8.尽量只采用三种基本的控制结构来编写程序。9.要模块化,使模块功能尽可能单一化,模块间的耦合能够清晰可见。10.利用信息隐蔽,确保每一个模块的独立性。11.不要修补不好的程序,要重新编写。也不要一味地追求代码的复用,要重新组织。12.对太大的程序,要分块编写、测试,然后再集成。13.对递归定义的数据结构尽量使用递归过程。4.输入/输出语句在编写输入/输出语句风格的规则:

对所有输入数据都进行检验检查输入项重要组合的合法性保持输入格式简单使用数据结束标记,不要要求用户指定数据的数目明确提示交互式输入的请求,详细说明可用的选择或边界数值当程序设计语言对格式有严格要求时,应保持输入格式与输入语句的要求一致设计良好的输出报表给所有输出数据加标志5.效率效率主要指处理机时间和存储器容量两个方面。虽然值得提出提高效率的要求,但是在进一步讨论这个问题之前应该记住三条原则:首先,效率是性能要求,因此应该在需求分析阶段确定效率方面的要求。软件应该像对它要求的那样有效,而不应该如同人类可能做到的那样有效。其次,效率是靠好设计来提高的。第三,程序的效率和程序的简单程度是一致的。不要牺牲程序的清晰性和可读性来不必要地提高效率。6.4程序设计质量的评价程序设计质量的评价需要考虑多方面的因素,不同的设计课题对质量要求会有不同的侧重点。 程序设计质量的最基本要求是正确性,现在更注重软件的易实用性、易维护性和易移植性。一、正确性

1、程序中没有语法错误

2、程序运行时没有发现明确的运行错误

3、程序中没有不适当的语句

4、用有效的测试数据,得到程序的正确结果

5、用无效的测试数据,得到程序的正确结果

6、用任何可能的数据,使程序在运行时得到 正确的结果。二、清晰的结构

1、是否用三种结构化格式表示程序的控制逻辑

2、是否有一个入口,一个出口

3、是否严格控制GOTO语句三、易使用性四、易维护性五、简单性六、易移植性6.5程序设计文档程序设计的依据是详细设计文档,软件编码阶段产生的主要文档是源程序。在编码结束前,应对每个程序模块的源程序进行静态分析和模块测试,并做好测试记录。静态分析和模块测试时,应检查下述内容:(1)程序是否与详细设计相符合,模块的运行是否正确(2)内部文件和程序的可读性如何(3)坚持结构化程序设计标准,语言使用是否得当6.6软件测试的目标和原则 基于不同的立场,存在着两种完全不同的测试目的。从用户的角度出发,普遍希望通过软件测试暴露软件中隐藏的错误和缺陷,以考虑是否可接受该产品。从软件开发者的角度出发,则希望测试成为表明软件产品中不存在错误的过程,验证该软件已正确地实现了用户的要求,确立人们对软件质量的信心。

G.Myers给出了关于测试的一些规则,这些规则也可以看作是测试的目标或定义:

·测试是为了发现程序中的错误而执行程序的过程;

·好的测试方案是极可能发现迄今为止尚未发现的错误的测试方案;

·成功的测试是发现了迄今为止尚未发现的错误的测试。换言之,测试的目的是:想以最少的时间和人力,系统地找出软件中潜在的各种错误和缺陷。如果我们成功地实施了测试,我们就能够发现软件中的错误。测试的附带收获是,它能够证明软件的功能和性能与需求说明相符合。实施测试收集到的测试结果数据为可靠性分析提供了依据。测试不能表明软件中不存在错误,它只能说明软件中存在错误。测试的原则:(1)在测试开始时,不要认为程序中没有错误(2)要避免测试自己编写的程序(3)测试用例要有输入数据和对应的预期结果(4)要对合理的输入数据和不合理的输入数据都 进行测试(5)除检查程序功能是否完备,还应检查程 序是否做了多余的工作(6)要精心设计测试方案,尽量把软件中的错 误测试出来(7)对发现错误较多的程序段,应进行更深入 的测试(8)应长期保存所有的测试用例,直至该程序 被废弃。6.7软件测试的方法6.7.1静态分析与动态测试软件测试按照测试过程是否执行程序来划分,有静态分析和动态测试两类。动态测试又分为黑盒法和白盒法两种。

1、静态分析不执行被测试软件,而是通过对需求分析说明书、软件设计说明是及源程序做结构检查,对流程图、编码进行分析,来找出软件错误。2、动态测试动态测试以执行程序并分析程序来查错。为了进行软件测试,需要预先准备好两种数据:(1)输入数据;(2)预期的输出结果我们把以发现错误为目标的、用于软件测试的输入数据及与之对应的预期输出结果,称为测试用例。怎么设计测试用例是动态测试的关键。6.7.2黑盒法与白盒法对于软件测试而言,黑盒测试法把程序看成一个黑盒子,完全不考虑程序的内部结构和处理过程。也就是说,黑盒测试是对程序接口进行的测试,它只检查程序功能是否能按照规格说明书的规定正常使用,程序是否能适当地接收输入数据产生正确的输出信息,并且保持外部信息(如:数据库或文件)的完整性。黑盒测试又称为功能测试。假设一个程序P有输入量X和Y及输出量Z。在字长为32位的计算机上运行。若X、Y取整数,按黑盒方法进行穷举测试:可能采用的测试数据组:232×232=264

如果测试一组数据需要1毫秒,一年工作365×24小时,完成所有测试需要5亿年。PXYZ黑盒法是最基本的测试法,主要发现以下错误:(1)是否有不正确的或遗漏的功能。(2)检查输入能否被正确地接收,软件能否正 确地输出结果(3)访问外部信息是否有错(4)性能上能否满足要求与黑盒测试法相反,白盒测试法的前提是可以把程序看成装在一个透明的白盒子里,也就是完全了解程序的结构和处理过程。这种方法按照程序内部的逻辑测试程序,检验程序中的每条通路是否都能按预定要求正确工作。白盒测试又称为结构测试。在软件测试时,常把黑盒法和白盒法联合起来进行,这也称为灰盒法。给出一个小程序的流程图,它包括了一个执行20次的循环。包含的不同执行路径数达520条,对每一条路径进行测试需要1毫秒,假定一年工作365×24小时,要想把所有路径测试完,需3170年。黑盒测试着重测试软件的功能需求,也就是说,黑盒测试让软件工程师设计出能充分检查程序所有功能需求的输入条件集。黑盒测试并不能取代白盒测试技术,它是与白盒测试互补的方法,它很可能发现白盒测试不易发现的其他不同类型的错误。白盒测试在测试过程的早期阶段进行,而黑盒测试主要用于测试过程的后期。黑盒测试故意不考虑程序的控制结构,而把注意力集中于信息域。测试准则 为了能设计出有效的测试方案,软件工程师必须充分理解并正确运用指导软件测试的基本准则。主要的测试准则如下所述。

·所有的测试都应该能追溯到用户需求。

·应该在测试开始之前的相当长时间,就制定出测试计划。

·把Pareto原理应用于软件测试。Pareto原理告诉我们,测试发现的错误中的80%很可能是由程序中20%的模块造成的。

·测试应该从“小规模”开始,并逐步进行“大规模”测试。

·穷举测试是不可能的。

·为了达到最佳的测试效果,应该由独立的第三方来从事测试工作。6.8软件测试的步骤测试过程按4个步骤进行,即单元测试、集成测试、确认测试和系统测试。6.8.1单元测试(模块测试):

单元测试的目的是检查每个模块是否能独立、正确的运行。单元测试通常在程序设计时进行。单元测试大量使用白盒测试技术,检查模块控制结构中的特定路径,以确保做到完全覆盖并发现最大数量的错误。

方式:人工测试计算机测试 这样两种类型的测试,完成单元测试工作。这两种类型的测试各有所长,互相补充。1.代码审查{人工测试}

人工测试源程序可以由编写者本人非正式地进行,也可以由审查小组正式进行。后者称为代码审查,它是一种非常有效的程序验证技术,对于典型的程序来说,可以查出30%~70%的逻辑设计错误和编码错误。审查小组最好由下述四人组成:组长,他应该是一个很有能力的程序员, 而且没有直接参与这项工程;程序的设计者;

程序的编写者;程序的测试者。实践表明,对于查找某些类型的错误来说,人工测试比计算机测试更有效;对于其他类型的错误来说则刚好相反。因此,人工测试和计算机测试是互相补充,相辅相成的,缺少其中任何一种方法都会使查找错误的效率降低。2.测试软件{计算机测试}

模块并不是一个独立的程序,因此必须为每个单元测试开发驱动程序和(或)存根程序。通常驱动程序也就是一个“主程序”,它接收测试数据,把这些数据传送给被测试的模块,并且印出有关的结果。存根程序代替被测试的模块所调用的模块。因此存根程序也可以称为“虚拟子程序”。它使用被它代替的模块的接口,可能做最少量的数据操作,印出对入口的检验或操作结果,并且把控制归还给调用它的模块。6.8.2集成测试:

在装配的同时进行测试,因此称为集成测试。集成测试同时解决程序验证和程序构造这两个问题。在集成过程中最常用的是黑盒测试用例设计技术,当然,为了保证覆盖主要的控制路径,也可能使用一定数量的白盒测试。

集成测试是测试和组装软件的系统化技术,在把模块按照设计要求组装起来的同时进行测试,主要目标是发现与接口有关的问题。由模块组装成程序时有两种方法。一种方法是先分别测试每个模块,再把所有模块按设计要求放在一起结合成所要的程序,这种方法称为非渐增式测试方法;另一种方法是把下一个要测试的模块同已经测试好的那些模块结合起来进行测试,测试完以后再把下一个应该测试的模块结合进来测试。这种每次增加一个模块的方法称为渐增式测试。1.自顶向下集成自顶向下的集成(结合)方法是一个日益为人们广泛采用的组装软件的途径。从主控制模块(主程序)开始,沿着软件的控制层次向下移动,从而逐渐把各个模块结合起来。在把附属于(以及最终附属于)主控制模块的那些模块组装到软件结构中去时,或者使用深度优先的策略,或者使用宽度优先的策略。

把模块结合进软件结构的具体过程由下述四个步骤完成:对主控制模块进行测试,测试时用存根程序代替所有直接附属于主控制模块的模块;根据选定的结合策略(深度优先或宽度优先),每次用一个实际模块代换一个存根程序(新结合进来的模块往往又需要新的存根程序);在结合进一个模块的同时进行测试;4.为了保证加入模块没有引进新的错误,可能需要进行回归测试(即,全部或部分地 重复以前做过的测试)。从第二步开始不断地重复进行上述过程,直到构造起完整的软件结构为止。图

自顶向下结合自顶向下集成图

自顶向下结合深度优先自顶向下集成图

自顶向下结合宽度优先自顶向下集成回归测试每当一个新模块作为集成测试的一部分加进来的时候,软件就发生了变化:建立了新的数据流路径,可能出现了新的I/O操作,激活了新的控制逻辑。这些变化可能使原来工作正常的功能出现问题。在集成测试的范畴中,所谓回归测试是指重新执行已经做过的测试的某个子集,以保证上述这些变化没有带来非预期的副作用。回归测试集(已执行过的测试用例的子集)包括下述三种不同的测试用例。检测软件全部功能的代表性测试用例专门针对可能受修改影响的软件功能 的附加测试。3.针对被修改过的软件成分的测试。2.自底向上集成自底向上测试从“原子”模块(即在软件结构最低层的模块)开始组装和测试。因为是从底部向上结合模块,总能得到需要的下层模块处理功能,所以不需要存根程序。用下述步骤可以实现自底向上的结合策略:把低层模块组合成实现某个特定的软件子功 能的簇;写一个驱动程序(用于测试的控制程序),协调测试数据的输入和输出;3.对由模块组成的子功能簇进行测试;去掉驱动程序,沿软件结构自下向上移动,把子功能簇组合起来形成更大的子功能簇。上述第2步到第4步实质上构成了一个循环。图

自底向上结合不同集成测试策略的比较:

自顶向下测试方法的主要优点是不需要测试驱动程序,能够在测试阶段的早期实现并验证系统的主要功能,而且能在早期发现上层模块的接口错误。自顶向下测试方法的主要缺点是需要存根程序,可能遇到与此相联系的测试困难,低层关键模块中的错误发现较晚,而且用这种方法在早期不能充分展开人力。可以看出,自底向上测试方法的优缺点与上述自顶向下测试方法的优缺点刚好相反。在测试实际的软件系统时,应该根据软件的特点以及工程进度安排,选用适当的测试策略。一般说来,纯粹自顶向下或纯粹自底向上的策略可能都不实用,人们在实践中创造出许多混合策略。6.8.3程序审查会和人工运行1.程序审查会成员:软件程序员和不参加设计的测试专家及调解员内容:(1)程序员逐句讲述程序的逻辑结构。 (2)审查会成员根据常见错误分析程序。2.人工运行 人工运行时,要求与会者模拟计算机运行程序,把各种测试情况,沿着程序逻辑走一遍,通过向程序员询问程序的逻辑设计情况来发现错误。6.8.4确认测试:

确认测试是对软件满足所有功能的、行为的和性能的需求的最终保证。在确认测试过程中常使用黑盒测试技术。确认测试也称验收测试。1.确认测试的范围确认测试必须有用户积极参与,或者以用户为主进行。确认测试时,主要使用真实数据,在实际运行环境下进行系统运行,目的是验证系统能否满足用户的需求。只有在验收测试通过后,才能进入下一阶段的工作。2.软件配置复查确认测试的一个重要内容是复查软件配置。3.Alpha和Beta测试如果一个软件是为许多客户开发的(例如,向大众出售的盒装软件产品),那么让每个客户都进行正式的验收测试是不现实的。在这种情况下,绝大多数软件开发商都使用被称为Alpha测试和Beta测试的过程,来发现那些看起来只有最终用户才能发现的错误。

Alpha测试由用户在开发者的场所进行,并且在开发者对用户的“指导”下进行测试。开发者负责记录错误和使用中遇到的问题。总之,Alpha测试是在受控的环境中进行的。

Beta测试由软件的最终用户们在一个或多个客户场所进行。与Alpha测试不同,开发者通常不在Beta测试的现场,因此,Beta测试是软件在开发者不能控制的环境中的“真实”应用。用户记录下在Beta测试过程中遇到的一切问题(真实的或想像的),并且定期把这些问题报告给开发者。接收到Beta测试期间报告的问题之后,软件开发者对产品进行修改,并准备向全体客户发布最终的软件产品。6.8.5平行运行比较重要的软件要有一段运行时间。此时新开发的系统与原系统同时运行,这称为平行运行。验收测试对任何系统都是必不可少的。对较大的系统,应召开程序审查会,对于重要的软件系统应采用平行运行,以免软件的错误造成不良后果6.9设计测试方案1.设计测试方案是测试阶段的关键技术问题。2.测试方案={测试目的,测试用例}3.测试用例={输入的测试数据,预期的输出结果}4.如何设计测试用例不同的测试数据发现程序错误的能力差别很大不可能进行穷尽的测试提高测试效率降低测试成本选用少量“最有效的”测试数据,做到尽可能完备的测试。6.9.1等价划分等价划分是一种黑盒测试方法,这种方法把所有可能的输入数据,即程序的输入域划分成若干部分,然后从每一部分中选取少数有代表性的数据做为测试用例。

等价类是指某个输入域的子集合。在该子集合中,各个输入数据对于揭露程序中的错误都是等效的。测试某等价类的代表值就等价于对这一类其它值的测试。划分等价类等价类的划分有两种不同的情况:

①有效等价类:是指对于程序的规格说明来说, 是合理的,有意义的输入数据构成的集合。

②无效等价类:是指对于程序的规格说明来说, 是不合理的,无意义的输入数据构成的集合。 在设计测试用例时,要同时考虑有效等价类和 无效等价类的设计。 划分等价类等价类的原则:

(1)如果输入条件规定了取值范围,或值的个数,则可以确立一个有效等价类和两个无效等价类。

例如,在程序的规格说明中,对输入条件有一句话:“……项数可以从1到999……”

则有效等价类是“1≤项数≤999”两个无效等价类是“项数<1”或“项数>999”。在数轴上表示成:

(2)如果输入条件规定了输入值的集合,或者是规定了“必须如何”的条件,这时可确立一个有效等价类和一个无效等价类。 例如,在C语言中对变量标识符规定为“以字母或下划线打头的……串”。那么所有以字母或下划线打头的构成有效等价类,而不在此集合内(不以字母打头)的归于无效等价类。

(3)如果输入条件是一个布尔量,则可以确定一个有效等价类和一个无效等价类。

(4)如果规定了输入数据的一组值,而且程序要对每个输入值分别进行处理。这时可为每一个输入值确立一个有效等价类,此外针对这组值确立一个无效等价类,它是所有不允许的输入值的集合。 例如,在教师上岗方案中规定对教授、副教授、讲师和助教分别计算分数,做相应的处理。因此可以确定4个有效等价类为教授、副教授、讲师和助教,一个无效等价类,它是所有不符合以上身分的人员的输入值的集合。(5)如果规定了输入数据必须遵守的规则,则可以确立一个有效等价类(符合规则)和若干个无效等价类(从不同角度违反规则)。例如,C语言规定“一个语句必须以分号‘;’结束”。这时,可以确定一个有效等价类“以‘;’结束”,若干个无效等价类“以‘:’结束”、“以‘,’结束”、“以‘’结束”等。(6)

如果规定了输入数据为整型,则可以划分出正整数、零和负整数等三个有效类。(7)

如果程序的处理对象是表格,则应该使用空表,以及含一项或多项的表。等价类划分的步骤(1)研究程序的功能说明,以确定输入数据是有效等价类还是无效等价类。(2)分析输出数据的等价类,以便根据输出数据的等价类导出相应的输入数据等价类。 在确立了等价类之后,建立等价类表,列出所有划分出的等价类。确立等价类测试用例 再从划分出的等价类中按以下原则选择测试用例:

(1)

为每一个等价类规定一个唯一编号;

(2)

设计一个新的测试用例,使其尽可能多地覆盖尚未被覆盖的有效等价类,重复这一步,直到所有的有效等价类都被覆盖为止;

(3)

设计一个新的测试用例,使其仅覆盖一个尚未被覆盖的无效等价类,重复这一步,直到所有的无效等价类都被覆盖为止。实例:在某一Pascal语言版本中规定:“标识符是由字母开头,后跟字母或数字的任意组合构成。有效字符数为8个,最大字符数为80个。”,并且规定:“标识符必须先说明,再使用。在同一说明语句中,标识符至少必须有一个。”用等价类划分的方法,建立输入等价类表下面选取了9个测试用例,它们覆盖了所有的等价类:①VARx,T1234567:REAL;

BEGINx:=3.414;T1234567:=2.732; ………… (1),(2),(4),(8),(9),(12),(14)②VAR:REAL; (3)③VARx,:REAL; (5)④VART12345678:REAL;(6)⑤VART12345……:REAL;(7)

多于80个字符⑥VART$:CHAR;(10)⑦VARGOTO:INTEGER;(11)⑧VAR2T:REAL;(13)⑨VARPAR:REAL;(15)BEGIN……PAR:=SIN(3.14*0.8)/6;作业:用等价类划分方法找出有效等价类和无效等价类,并作出测试用例。某城市电话号码由三部分组成,内容如下:第一部分是地区码,地区码可以是空白或三位数字;第二部分是前缀为非零和非一开头的三位数;第三部分是后缀为四位数。6.9.2边界值分析法经验表明,处理边界情况时程序最容易发生错误。因此,设计使程序运行在边界情况附近的测试方案,暴露出程序错误的可能性更大一些。使用边界值分析方法设计测试方案首先应该确定边界情况,这需要经验和创造性,通常输入等价类和输出等价类的边界,就是应该着重测试的程序边界情况。比如,在做三角形计算时,要输入三角形的三个边长:A、B和C。我们应注意到这三个数值应当满足A>0、B>0、C>0、A+B>C、A+C>B、B+C>A,才能构成三角形。但如果把六个不等式中的任何一个大于号“>”错写成大于等于号“≥”,那就不能构成三角形。选取的测试数据应该刚好等于、刚刚小于和刚刚大于边界值。也就是说,按照边界值分析法,应该选取刚好等于、稍小于和稍大于等价类边界值的数据作为测试数据,而不是选取每个等价类内的典型值或任意值作为测试数据。用边界值分析设计测试用例应遵循的原则:1、如果输入条件规定了取值范围,则应对该范围的边界内附近,恰好在边界和在边界外附近(无效等价类中)设计测试用例。如:规定1~5千克邮件收费2元,应对0.9,1,1.1,4.9,5,5.1千克设计测试用例。2、如果输入条件规定了数据的个数,则应对最少个数,最多个数,比最少个数少1,比最大个数多1等情况设计测试用例。如:输入文件有1~255个记录,则应分别设计0,1,255,256个记录的输入文件的测试用例。3、针对规格说明中的每个输出条件使用前面的1和2原则。如:计算折扣量,最低折扣为0元,最高为1000元,则要设计使它们恰好产生0元或1000元的结果。以及负值或稍大于1000元的结果(如果可能的话)。4、如果程序规格说明中提到的输入或输出域是个有序的集合(如顺序文件,线性表等)。应选有序集的第一个和最后一个元素作为测试用例等价类和边界值方法的区别:(1)边界值不是从等价类中随便取一个数据作为代表,而是选一个或几个特定值,使这个等价类的每个边界都作为测试的目标。(2)边界值分析不仅要考虑输入条件,而且要考虑输出条件(输出等价类)。 一般联合使用等价类划分和边界值分析两种方法。6.9.3错误推测法人们也可以靠经验和直觉推测程序中可能存在的各种错误,从而有针对性地编写检查这些错误的例子。。它的基本想法是列举出程序中可能有的错误和容易发生错误的特殊情况,并且根据它们选择测试方案。6.9.4逻辑覆盖法白盒法根据程序逻辑结构进行测试,逻辑覆盖法是一系列测试过程的总称,这些测试是逐渐地、越来越完整地进行路径测试。从覆盖程序的详细程度来考虑,逻辑覆盖有以下几种不同的测试过程:

语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、条件组合覆盖、点覆盖、边覆盖和路径覆盖例(A>1)

and

(B=0)(A=2)

or

(X>1)X=X/AX=X+1TTFFabdce图

程序流程图L1(ace)={(A>1)and

(B=0)}and

{(A=2)or

(X/A>1)}=(A>1)and(B=0)and(A=2)or(A>1)and(B=0)and(X/A>1)=(A=2)and(B=0)

or

(A>1)and(B=0)and(X/A>1)

L2(abd)=not{(A>1)and(B=0)}

and

not{(A=2)or(X>1)}={not(A>1)ornot(B=0)}and

{not(A=2)andnot(X>1)}=

not(A>1)andnot(A=2)andnot(X>1)

or

not(B=0)andnot(A=2)andnot(X>1)=

not(A>1)andnot(X>1)

or

not(B=0)andnot(A=2)andnot(X>1)L3(abe)=not

{(A>1)and(B=0)}

and

{(A=2)or(X>1)}={not(A>1)ornot(B=0)}

and

{(A=2)or(X>1)}=not(A>1)and(A=2)

or

not(A>1)and

(X>1)

or

not(B=0)

and(A=2)

or

not(B=0)and(X>1)L4(acd)={(A>1)and(B=0)}

and

not

{(A=2)or(X/A>1)}=(A>1)and

(B=0)and

not(A=2)and

not(X/A>1)语句覆盖

语句覆盖就是设计足够多个测试用例,运行被测程序,使得每一可执行语句至少执行一次。在图例中,正好所有的可执行语句都在路径L1上,所以选择路径L1设计测试用例,就可以覆盖所有的可执行语句。

测试用例的设计格式如下

【输入的(A,B,X),输出的(A,B,X)】为图例设计满足语句覆盖的测试用例是:

【(2,0,4),(2,0,3)】,覆盖路径L1图

被测试模块的流程图A=2B=0X=4判定覆盖判定覆盖就是设计若干个测试用例,运行被测程序,使得程序中每个判断的取真分支和取假分支至少经历一次。判定覆盖又称为分支覆盖。每个语句+每个判定的每个分支对于图例,如果选择路径L1和L2,就可得满足要求的测试用例: 【(2,0,4),(2,0,3)】覆盖ace【L1】

【(1,1,1),(1,1,1)】覆盖abd【L2】如果选择路径L3和L4,还可得另一组可用的测试用例:【(2,1,1),(2,1,2)】覆盖abe【L3】

【(3,0,3),(3,0,1)】覆盖acd【L4】图

被测试模块的流程图A=3,B=0,X=3A=2,B=1,X=1问题:只覆盖了2条路径,是全部的一半条件覆盖条件覆盖就是设计若干个测试用例,运行被测程序,使得程序中每个判断的每个条件的可能取值至少执行一次。在图例中,我们事先可对所有条件的取值加以标记。例如,对于第一个判断:条件A>1取真为,取假为

条件B=0取真为,取假为对于第二个判断:

条件A=2取真为,取假为

条件X>1取真为,取假为T4测试用例

覆盖分支

条件取值【(2,0,4),(2,0,3)】

L1(c,e)

【(1,0,1),(1,0,1)】

L2(b,d)

【(2,1,1),(2,1,2)】

L3(b,e)或

测试用例

覆盖分支

条件取值【(1,0,3),(1,0,4)】

L3(b,e)

【(2,1,1),(2,1,2)】

L3(b,e)

被测试模块的流程图A>1,A≤1,B=0,B≠0A=2,A≠2,X>1,X≤1A>1,B=0,A=2,X>1A=2,B=0,X=4A≤1,B≠0A≠2,,X≤1A=1,B=1,X=1

判定-条件覆盖就是设计足够的测试用例,使得每个判断表达式的所有可能取值至少执行一次,每个判断中的每个条件的可能取值至少执行一次。判定-条件覆盖

测试用例

覆盖分支

条件取值【(2,0,4),(2,0,3)】L1(c,e)【(1,1,1),(1,1,1)】L2(b,d)

被测试模块的流程图即满足条件覆盖又满足逻辑覆盖A>1,A≤1,B=0,B≠0A=2,A≠2,X>1,X≤1A>1,B=0,A=2,X>1A=2,B=0,X=4A≤1,B≠0A≠2,,X≤1A=1,B=1,X=1条件组合覆盖条件组合覆盖就是设计足够的测试用例,运行被测程序,使得每个判断的所有可能的条件取值组合至少执行一次。既 ①A>1,B=0作 ②A>1,B≠0作 ③A≯1,B=0作 ④A≯1,B≠0作 ⑤A=2,X>1作

⑥A=2,X≯1作

⑦A≠2,X>1作

⑧A≠2,X≯1作测试用例

覆盖条件

覆盖组合【(2,0,4),(2,0,3)】(L1) ①,⑤【(2,1,1),(2,1,2)】(L3) ②,⑥【(1,0,3),(1,0,4)】(L3) ③,⑦【(1,1,1),(1,1,1)】(L2)

④,⑧把程序流程图中每一个符号看成是一个点,原来连接不同处理符号的箭头改为连接不同点的有向弧,就可得到一个有向图,称之为程序图(流图)。点覆盖测试要求选取足够多的数据,使得程序执行时至少经过程序图中的每个点一次。点覆盖和语句覆盖的要求是相同的。点覆盖符号○为程序图的一个结点,表示一个或多个无分支的PDL语句或源程序语句。箭头为边,表示控制流的方向。在选择或多分支结构中,分支的汇聚处应有一个汇聚结点。边和结点圈定的区域叫做区域,当对区域计数时,图形外的区域也应记为一个区域。如果判断中的条件表达式是由一个或多个逻辑运算符

(OR,AND,...)

连接的复合条件表达式,则需改为一系列只有单个条件的嵌套的判断。

把程序流程图映射成程序图(左边)程序流程图;(右边)程序图应选择路径:s→a→c→b→d→e测试用例:A=3,b=0边覆盖边覆盖要求选取足够多的测试数据,使程序执行路径至少经过程序图中每条边一次。即:A=3,B=0;执行路径为1→4→5→6→7A=2,B=1;执行路径为1→2→3

还有其他的测试数据 么?路径覆盖路径覆盖要求选取足够多的测试数据,使程序的每条可能执行路径都至少执行一次。1、1→4→5→6→72、1→2→33、1→2→6→74、1→4→5→3测试数据依次为:A=3,B=0A=1,B=1A=4,B=0A=1,B=2基本路径测试

基本路径测试是一种白盒测试技术。使用这种技术设计测试用例时,首先计算过程设计结果的逻辑复杂度,并以该复杂度为指南定义执行路径的基本集合,从该基本集合导出的测试用例可以保证程序中的每条语句至少执行一次,而且每个条件在执行时都将分别取true(真)和false(假)值。 使用基本路径测试技术设计测试用例的步骤如下:1.根据过程设计结果画出相应的流图101112131234567892.计算流图的环形复杂度环形复杂度定量度量程序的逻辑复杂性。有了描绘程序控制流的流图之后,可以用下述三种方法之一来计算环形复杂度。(1)流图中的区域数等于环形复杂度。(2)流图G的环形复杂度V(G)=E-N+2,其中E是流图中边的条数,N是流图中节点数。(3)流图G的环形复杂度V(G)=P+1,其中P是流图中判定节点的数目。使用上述任何一种方法,都可以计算上图所示流图的环形复杂度为7。3.确定线性独立路径的基本集合所谓独立路径是指至少引入程序的一个新处理语句集合或一个新条件的路径,用流图术语描述,独立路径至少包含一条在定义该路径之前不曾用过的边。使用基本路径测试法设计测试用例时,程序的环形复杂度决定了程序中独立路径的数量,而且这个数是确保程序中所有语句至少被执行一次所需的测试数量的上界。对于上图所描述的过程来说,由于环形复杂度为7,因此共有7条独立路径。例如,下面列出了7条独立路径:路径1:1-2-10-11-13

路径2:1-2-10-12-13

路径3:1-2-3-10-11-13

路径4:1-2-3-4-5-8-9-2-...

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

温馨提示

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

评论

0/150

提交评论