《软件工程:第07章实现.ppt》由会员分享,可在线阅读,更多相关《软件工程:第07章实现.ppt(164页珍藏版)》请在三一办公上搜索。
1、1,第七章 实现(编码与测试),Implementation=Coding+Testing,实现:编码与测试,编码将软件设计的结果转化成程序设计语言编写的计算机程序。开发人员对软件的最小设计单位-模块进行单元测试。,测试熟悉软件测试的步骤:单元测试、集成测试、确认测试。掌握软件测试的方法:白盒测试、黑盒测试、灰盒测试。掌握软件调试(纠错)的方法:调试过程、调试方法。了解软件可靠性基本概念及估算方法。,第七章 实现(编码与测试),7.1 编码7.2 软件测试基础 7.3 单元测试7.4 集成测试7.5 确认测试7.6 白盒测试技术7.7 黑盒测试技术7.8 调试7.9 软件可靠性,3,7.1 编
2、码,编码就是把软件设计结果翻译成用某种程序设计语言书写的程序。7.1.1 选择程序设计语言7.1.2 编码风格1.程序内部的文档2.数据说明3.语句构造4.输入输出5.效率,7.1.1 选择程序设计语言,为什么程序设计语言是人和计算机通信的最基本的工具,它的特点必然会影响人的思维和解题方式,会影响人和计算机通信的方式和质量,也会影响其他人阅读和理解程序的难易程度。因此,编码之前的一项重要工作就是选择一种适当的程序设计语言。,实用选择标准:用户对编程语言的要求。可以使用的编译程序。可以得到的软件工具。工程规模。程序员的编程语言知识。软件可移植性要求。软件的应用领域。,效率:阅读理解、开发、测试、
3、运行、维护,7.1.2 编码风格,程序实际上也是一种供人阅读的文章,应该使程序具有良好的风格。“好的”程序应遵循的规则:程序文档:源程序文档化,易于理解的标识符命名、适当的注释、清晰的程序视觉组织等。数据说明:易于理解,便于查阅。语句构造:结构化,简单、直观,技巧不过份。输入输出:遵循人机界面设计准则。效率:效率满足需求;不要为了追求效率而过份使用技巧,牺牲程序的清晰性、可读性。,(1)程序文档,程序中的标识符(名字)程序中的注释程序的视觉组织,符号名的命名,符号名即标识符,包括模块名、变量名、常量名、标号名、子程序名、数据区名以及缓冲区名等。名字的意义这些名字应能反映它所代表的实际东西,应有
4、一定实际意义。例如,表示次数的量用Times,表示总量的用Total,表示平均值的用Average,表示和的量用Sum等。名字的使用名字不是越长越好,应当选择精炼的意义明确的名字。必要时可使用缩写名字,但这时要注意缩写规则要一致。要给每一个名字加注释。在一个程序中,一个变量只应用于一种用途。,夹在程序中的注释是程序员与日后的程序读者之间通信的重要手段。注释决不是可有可无的。一些正规的程序文本中,注释行的数量占到整个源程序的1/3到1/2,甚至更多。注释分为序言性注释和功能性注释。,程序的注释,序言性注释通常置于每个程序模块的开头部分,它应当给出程序的整体说明,对于理解程序本身具有引导作用。序言
5、性注释包括:程序标题;有关本模块功能和目的的说明;主要算法说明:算法概要、大意;接口说明:包括调用形式,参数描述,子程序清单;有关数据描述:重要的变量及其用途,约束或限制条件,以及其它有关信息;模块位置:在哪一个源文件中,或隶属于哪一个软件包;开发简历:模块设计者,复审者,复审日期,修改日期及有关说明等。,序言性注释,功能性注释嵌在源程序体中,用以描述其后的语句或程序段是在做什么工作,或是执行了下面的语句会怎么样,而不要解释下面怎么做。要点描述一段程序,而不是每一个语句;用缩进和空行,使程序与注释容易区别;注释要正确。例如:/*ADD AMOUNT TO TOTAL*/TOTAL=AMOUNT
6、TOTAL上面注视不清楚,如果注明把月销售额计入年度总额,便使读者理解了下面语句的意图:/*ADD MONTHLY-SALES TO ANNUAL-TOTAL*/TOTAL=AMOUNTTOTAL,功能性注释,恰当地利用空格,可以突出运算的优先性,避免发生运算的错误。例如,将表达式(A17)ANDNOT(B49)ORC写成(A17)AND NOT(B49)OR C自然的程序段之间可用空行隔开;移行也叫做向右缩格。它是指程序中的各行不必都在左端对齐,都从第一格起排列。这样做使程序完全分不清层次关系。对于选择语句和循环语句,把其中的程序段语句向右做阶梯式移行。使程序的逻辑结构更加清晰。,例如,两重
7、选择结构嵌套写成下面的移行形式,层次就清楚得多。IF()THEN IF()THEN ELSE ENDIF ELSE ENDIF,视觉组织:使用空格、空行和移行,数据说明指程序中用到的常量、变量、文件等数据对象的定义。在设计阶段已经确定了数据结构的组织及其复杂性。在编写程序时,则需要注意数据说明的风格。为了使程序中数据说明更易于理解和维护,必须注意以下几点:a.数据说明的次序应该标准化。有次序易查阅,能加速测试、调试和维护的过程。b.当多个变量名在一个语句中说明时,应该按字母顺序排列这些变量。c.如果设计时使用了一个复杂的数据结构,则应该用注解说明用程序设计语言实现这个数据结构的方法和特点。,(
8、2)数据说明,数据说明的次序,数据说明 常量说明 简单变量类型说明 数组说明 公用数据块说明 所有的文件说明,数据类型说明 整型量说明 实型量说明 字符量说明 逻辑量说明,数据说明有次序易查阅,能加速测试、调试和维护的过程。,变量名按字母顺序排列,b.当多个变量名在一个语句中说明时,应该按字母顺序排列这些变量,便于查找。例如,把 integer size,length,width,cost,price 写成 integer cost,length,price,size,width,(3)语句构造,AI=AIAT;AT=AIAT;AI=AIAT;,WORK=AT;AT=AI;AI=WORK;,构
9、造语句时应该遵循的原则是,每个语句都应该简单而直接,不能为了提高效率而使程序变得过分复杂;也不要刻意追求技巧性,使程序编写得过于紧凑。,例:语句构造,int i,j;for(i=1;i=n;i+)for(j=1;j=n;j+)Vij(ij)*(ji),for(i1;i=n;i+)for(j1;j=n;j+)if(i=j)Vij 1;else Vij 0;,有助于使语句简单明了的规则,不要为了节省空间而把多个语句写在同一行;尽量避免复杂的条件测试;尽量减少对“非”条件的测试;避免大量使用循环嵌套和条件嵌套;利用括号使逻辑表达式或算术表达式的运算次序清晰直观。,例:使用not(!)操作的例子将 i
10、f(!(char0|char 9)改成 if(char=0&char=9)不要让读者绕弯子想!,(4)输入输出,在设计和编写程序时应该考虑下述有关输入输出风格的规则:对所有输入数据都要进行检验,识别错误输入,以保证每个数据的有效性;检查输入项的各种重要组合的合法性,必要时报告输入状态信息;使得输入的步骤和操作尽可能简单,并保持简单的输入格式;输入数据时,应允许使用自由格式输入;应允许缺省值;输入一批数据时最好使用输入结束标志,而不要由用户指定输入数据数目;在交互式输入输入时,要在屏幕上使用提示符明确提示交互输入的请求,指明可使用选择项的种类和取值范围。同时,在数据输入的过程中和输入结束时,也要
11、在屏幕上给出状态信息;当程序设计语言对输入输出格式有严格要求时,应保持输入格式与输入语句的要求的一致性;给所有的输出加注解,并设计输出报表格式。,影响输入输出风格的其它因素,输入输出风格还受到许多其它因素的影响。如输入输出设备(例如终端的类型,图形设备,数字化转换设备等)、用户的熟练程度、以及通信环境等。,(5)程序效率,程序效率程序的效率是指程序的执行速度及程序所需占用的内存的存储空间。程序编码是最后提高运行速度和节省存储的机会,因此在此阶段不能不考虑程序的效率。效率准则需求阶段:效率是一个性能要求,应当在需求分析阶段给出要求。软件效率以需求为准,不应以人力所及为准。设计阶段:好的设计可以提
12、高效率。编码阶段:程序的效率与程序的简单性相关,不要牺牲程序的清晰性和可读性来不必要地提高效率。效率问题程序运行时间效率存储器效率输入输出的效率,22,程序运行时间效率,源程序的效率直接由详细设计阶段确定的算法的效率决定,但是,写程序的风格也能对程序的执行速度和存储器要求产生影响。在把详细设计结果翻译成程序时,总可以应用下述规则:写程序之前先简化算术的和逻辑的表达式;仔细研究嵌套的循环,以确定是否有语句可以从内层往外移;尽量避免使用多维数组;尽量避免使用指针和复杂的表;使用执行时间短的算术运算;不要混合使用不同的数据类型;尽量使用整数运算和布尔表达式。在效率是决定性因素的应用领域,尽量使用有良
13、好优化特性的编译程序,以自动生成高效目标代码。,23,存储器效率,在大中型计算机系统中,存储限制不再是主要问题。在这种环境下,对内存采取基于操作系统的分页功能的虚拟存储管理。存储效率与操作系统的分页功能直接有关。采用结构化程序设计,将程序功能合理分块,使每个模块或一组密切相关模块的程序体积大小与每页的容量相匹配,可减少页面调度,减少内外存交换,提高存储效率。在微型计算机系统中,存储器的容量对软件设计和编码的制约很大。因此要选择可生成较短目标代码且存储压缩性能优良的编译程序,有时需采用汇编程序。提高存储器效率的关键是程序的简单性。,24,输入输出的效率,输入输出可分为两种类型:面向人(操作员)的
14、输入输出面向设备的输入输出高效的输入输出是如果操作员能够十分方便、简单地录入输入数据,或者能够十分直观、一目了然地了解输出信息,则可以说面向人的输入输出是高效的。关于提高设备输入/输出效率的指导原则:输入/输出的请求应当最小化;对于所有的输入/输出操作,安排适当的缓冲区,以减少频繁的信息交换。对辅助存储(例如磁盘),选择尽可能简单的,可接受的存取方法;对辅助存储的输入/输出,应当成块传送;对终端或打印机的输入/输出,应考虑设备特性,尽可能改善输入/输出的质量和速度;任何不易理解的,对改善输入/输出效果关系不大的措施都是不可取的;任何不易理解的所谓“超高效”的输入/输出是毫无价值的。,7.2 软
15、件测试基础,7.2.1软件测试的目标7.2.2软件测试准则7.2.3测试方法7.2.4测试步骤7.2.5测试阶段的信息流,7.2.1 软件测试的目的,引子软件错误将造成工作的巨大损失例:1963年,美国,飞往火星的火箭爆炸,损失$10 million。原因:ORTRAN循环:DO 5 I=1,3 误写为 DO 5 I=1.3。软件测试的工作量占整个项目工作量比重极大软件测试的工作量约占整个项目工作量的40左右,对于要求极高的系统测试工作量还要成倍增加。例:微软Exchange 2000和Windows 2000中的人员结构见下表,软件测试的目的:问题与观点,问题:为什么需要这么多人、花这么多代
16、价进行测试?目的何在?观点:观点一:软件测试的目的是为了“证明程序正确”。观点二:软件测试的目的是为了“找出程序中的错误”。定义:Myers对软件测试目的提出以下观点和定义:(1)软件测试是为了发现错误而执行程序的过程。(2)一个好的测试用例能够发现至今尚未发现的错误。(3)一个成功的测试是发现了至今尚未发现的错误的测试。测试只能证明程序中有错误,不能证明程序中没有错误,正确!,28,软件测试的目的,在测试阶段测试人员努力设计出一系列测试方案,目的却是为了“破坏”已经建造好的软件系统竭力证明程序中有错误不能按照预定要求正确工作。暴露问题并不是软件测试的最终目的,发现问题是为了解决问题,测试阶段
17、的根本目标是尽可能多地发现并排除软件中潜藏的错误,最终把一个高质量的软件系统交给用户使用。通常想象的“测试是为了表明程序是正确的”,“成功的测试是没有发现错误的测试”是不正确的。测试的目标决定了测试方案的设计。如果为了表明程序是正确的而进行测试,就会设计一些不易暴露错误的测试方案;相反,如果测试是为了发现程序中的错误,就会力求设计出最能暴露错误的测试方案。,测试决不能证明软件是正确的,也不能证明错误的不存在,它只能力求证明错误的存在。,29,软件测试的有关问题,软件缺陷是什么?谁执行测试?开发者?单独的测试人员?两方面人员?测试什么?每个部分都测试?测试软件中高风险部分?什么时候测试?怎样测试
18、?测试应进行到什么程度?,30,软件缺陷,缺点(defect)谬误(fault)问题(problem)错误(error)异常(anomaly)偏差(variance)失败(failure)缺陷(bug),这些缺陷都是描述软件失败的术语!,SDE/T,负责写测试工具代码,并利用测试工具对软件进行测试;或者开发测试工具为软件测试工程师服务。,负责理解产品的功能要求,然后对其进行测试,检查软件有没有错误(Bug),决定软件是否具有稳定性,并写出相应的测试规范和测试案例,STE,测试工具软件开发工程师(Software Development Engineer in Test,简称SDE/T),软件测
19、试有关人员,软件测试工程师(Software Test Engineer,简称STE),32,7.2.2 软件测试准则,(1)所有测试都应该能追溯到用户需求。(2)应“尽早地规划和不断地进行软件测试”。(3)将pareto原则(80%:20%)应用于软件测试。(4)应从“小规模”测试开始,逐步进行“大规模”测试。(5)穷举测试是不可能的。(6)应由独立的第三方从事测试工作。(7)测试用例应由输入数据和预期的输出结果两部分组成。(8)程序修改后要回归测试。(9)应长期保留测试用例,直至系统废弃。,软件测试准则,(1)所有测试都应该能追溯到用户需求软件测试的目标是发现错误。从用户的角度看,最严重的
20、错误是导致程序不能满足用户需求的那些错误。软件中的问题根源可能在开发前期的各阶段解决、纠正错误也必须追 溯到前期工作。,可追溯性,软件测试准则(续),(2)尽早地规划和不断地进行软件测试把“尽早地和不断地进行软件测试”作为软件开发者的座右铭。概要设计时应完成测试计划,详细的测试用例定义可在设计模型确定后开始,所有测试可在任何代码被产生之前进行计划和设计。软件测试不等于程序测试。软件测试应贯穿于软件定义与开发的整个期间;程序编写的许多错误是“先天的”。据统计,查出的软件错误中,属于需求分析和软件设计的错误约占 64%,属于程序编写的错误仅占 36%。,计划,需求分析,设计,编码,测试,错误扩展模
21、型,36,软件测试准则(续),(3)在软件测试中应用pareto原则 pareto原则指出:测试发现的错误中的80%很可能是由程序中20%的模块造成的。当然,问题是怎样找出这些可疑的模块并彻底地测试它们。(4)从“小规模”到“大规模”测试应该从“小规模”测试开始,并逐步进行“大规模”测试。通常,首先重点测试单个程序模块,然后把测试重点转向在集成的模块簇中寻找错误,最后在整个系统中寻找错误。,软件测试准则(续),(5)注意测试用例的组成测试用例应由输入数据和预期的输出结果两部分组成,并兼顾合理的输入和不合理的输入数据(6)穷举测试是不可能的所谓穷举测试就是把程序所有可能的执行路径都检查一遍的测试
22、。由于程序的执行路径庞大(路径组合爆炸),受时间、人力及其他资源的限制,穷举法难以实施。经精心设计,可用穷举法覆盖所有的程序逻辑遍历程序流图的所有的边(即每个语句都被执行一次!),达到所要求的一定的测试可靠性。,穷举测试例,例2:如图,设程序含4个分支,循环次数20,从A到B的可能路径有:51+52+5201014(条)执行时间:设测试一次需2ms,则穷举测试需5亿年。,例1:输入三角形的三条边长,可采用的测试用例数(设字长16位)为(次)216 X216 X216 3X1010(次)执行时间:设测试一次需1ms,约需一万年。,软件测试准则(续),(7)为了达到最佳的测试效果,应该由独立的第三
23、方从事测试工作。所谓“最佳效果”是指有最大可能性发现错误的测试。由于心理上的原因,开发软件的软件工程师并不是完成全部测试工作的最佳人选,通常他们主要承担模块测试工作。而其他测试应由第三方承担。(8)程序修改后要回归测试程序正常修改或纠错修改之后,可能引入新的错误,因此必须进行回归测试。(9)应长期保留测试用例,直至系统废弃。保留测试用例,可用于回归测试、新版本测试。也可在程序出现错误之后,进行分析,寻找出错原因、漏测原因。,软件测试的策略和方法,静态测试方法,动态测试方法,人工测试方法,计算机辅助静态分析方法,白盒测试方法,黑盒测试方法,7.2.3 测试方法,静态测试,静态测试:基本特征是在对
24、软件需求规格说明书、软件设计说明书、源程序进行分析、检查和审阅,不实际运行被测试的软件。分析、检查和审阅内容:是否符合相关的标准和规范;通过结构分析、流图分析、符号执行等,指出软件缺陷。效果静态测试约可找出3070%的逻辑设计错误.,动态测试:通过运行软件来检验软件的动态行为和运行结果的正确性。动态测试的两个基本要素:被测试程序测试数据(测试用例)动态测试方法:(1)选取定义域有效值,或定义域外无效值;(2)对已选取值决定预期的结果;(3)用选取值执行程序;(4)执行结果与预期的结果相比,不吻和则程序有错。,测试用例ID目的前提输入预期输出后果执行历史日期 结果 版本 执行人,动态测试,动态测
25、试技术,白盒测试法(White Box Testing)把程序看成装在一个透明的白盒子里,测试者完全知道程序的结构和处理算法,用于检测程序中的主要执行通路是否都能按预定要求正确工作。如果知道软件的内部工作过程,可以通过测试来检验产品内部动作是否按照规格说明书的规定正常进行。白盒测试又称为结构测试。黑盒测试法(Black Box Testing)把程序看作一个黑盒子,完全不考虑程序的内部结构和处理过程。只检查程序功能是否按照规格说明书的规定正常使用。如果已经知道了软件应该具有的功能,可以通过测试来检验是否每个功能都能正常使用。黑盒测试又称为功能测试。,白盒测试也叫玻璃盒测试(Glass Box
26、Testing),对软件的过程性细节做细致的检查。这一方法是把测试对象看作一个打开的盒子,它允许测试人员利用程序内部的逻辑结构及有关信息,来设计或选择测试用例,对程序所有逻辑路径进行测试。,白盒测试的内容,对程序模块的所有独立执行路径至少测试一次,对所有的逻辑判定,取“真”与取“假”的两种情况都能至少测试一次。,在循环的边界和运行边界限内执行循环体,测试内部数据结构的有效性。,白盒测试(White Box Testing),已知产品的功能设计规格,可以进行测试证明每个实现了的功能是否符合要求。,黑盒测试的内容,黑盒测试(Black Box Testing),7.2.4 测试步骤,1.模块测试-
27、程序的单元把每个模块作为一个单独的实体来测试。模块测试通常又称为单元测试。在测试中所发现的往往是编码和详细设计的错误。2.子系统测试-程序的局部把经过单元测试的模块放在一起形成一个子系统来测试。模块相互间的协调和通信是这个测试过程中的主要问题,着重测试模块的接口。3.系统测试-子系统的集成把经过测试的子系统装配成一个完整的系统来测试。验证系统能否提供需求说明书中指定的功能,动态特性是否符合预定要求。其中发现的往往是软件设计中的错误,也可能是需求说明中的错误。子系统测试和系统测试,都兼有检测和组装两重含义,通常称为集成测试。4.验收测试-用户参与系统整体测试把软件系统作为单一的实体进行测试,测试
28、内容与系统测试基本类似,但它是在用户积极参与下进行的,而且主要使用实际数据进行测试。目的是验证系统确实能够满足用户的需要,其中发现的往往是系统需求说明书中的错误。验收测试也称为确认测试。5.平行运行-新旧系统共存平行运行:就是同时运行新开发出来的系统和将被它取代的旧系统,以便比较新旧两个系统的处理结果。这样做的具体目的有如下几点:(1)可以在准生产环境中运行新系统而又不冒风险;(2)用户能有一段熟悉新系统的时间;(3)可以验证用户指南和使用手册之类的文档;(4)能够以准生产模式对新系统进行全负荷测试,进一步验证性能指标。,7.2.5 测试阶段的信息流,测试阶段的的输入信息有两类:(1)软件配置
29、,包括需求说明书、设计说明书和源程序清单等;(2)测试配置,包括测试计划和测试方案。测试方案包括:测试用例:测试时使用的输入数据;每组输入数据预定要检验的功能,以及每组输入数据预期应该得到的正确输出。测试结果和预期结果不一致时,程序中有错误,进入调试阶段。由程序的编写者负责调试。如果经常出现要求修改设计的严重错误,那么软件的质量和可靠性是值得怀疑的。如果软件功能完成得很正常,遇到的错误也很容易改正,仍然应该考虑两种可能:(1)软件的可靠性是可以接受的;(2)所进行的测试尚不足以发现严重的错误。如果经过测试,一个错误也没有被发现,则很可能是对测试配置思考不充分,以致不能暴露软件中潜藏的错误。,测
30、试阶段的信息流,测试,软件配置,结果分析评价,测试结果,调试排错,改正的软件,预期结果,可靠性模型及分析,预测的可靠性,错误,出错率数据,测试配置,测试工具,需求规格说明书软件设计说明书 被测源程序,测试计划 测试用例(测试数据)测试驱动程序,测试数据自动生成程序、静态分析程序、动态分析程序、测试结果分析程序、以及驱动测试的测试数据库等。,图7.1 测试阶段的信息流,49,软件测试的对象,软件测试并不等于程序测试。软件测试应贯穿于软件定义与开发的整个期间。因此,需求分析、概要设计、详细设计以及程序编码等所得到的文档资料,包括需求规格说明、概要设计说明、详细设计规格说明以及源程序,都应成为软件测
31、试的对象。软件=程序+文档!,7.3 单元测试,7.3.1测试重点7.3.2(人工)代码审查7.3.3计算机测试,7.3.1测试重点,1.模块接口对通过模块接口的数据流进行测试,如果数据不能正确地进出,所有其他测试都是不切实际的。主要检查下述几个方面:参数的数目、次序、属性或单位系统与变元是否一致;是否修改了只作输入用的变元;全局变量的定义和用法在各个模块中是否一致。2.局部数据结构对模块来说,局部数据结构是常见的错误来源。主要检查内容包括局部数据说明、初始化、默认值等方面的错误。3.重要的执行通路由于不可能进行穷尽测试,在单元测试期间选择最有代表性、最可能发现错误的执行通路进行测试就是十分关
32、键的。应该设计测试方案用来发现由于错误的计算、不正确的比较或不适当的控制流而造成的错误。4.出错处理通路好的设计应该能预见出现错误的条件,并且设置适当的处理错误的通路。应该着重测试下述一些可能发生的错误:(1)对错误的描述是难以理解的;(2)记下的错误与实际遇到的错误不同;(3)在对错误进行处理之前,错误条件已经引起系统干预;(4)对错误的处理不正确;(5)描述错误的信息不足以帮助确定造成错误的位置。5.边界条件边界测试在单元测试中非常重要。软件常常在它的边界上失效。应使用刚好小于、刚好等于和刚好大于最大值或最小值的测试方案,非常可能发现软件中的错误。,7.3.2 代码审查,代码审查 由审查小
33、组人工测试源程序称为代码审查。是一种非常有效的程序验证技术,对于典型的程序来说,可以查出30%70%的逻辑设计错误和编码错误。审查小组组成:(1)组长,应该是一个很有能力的程序员,而且没有直接参与这项工程;(2)程序的设计者;(3)程序的编写者;(4)程序的测试者。,审查的步骤:小组成员先研究设计说明书,力求理解这个设计。由设计者扼要地介绍他的设计。审查会上程序的编写者逐个语句地解释是怎样用程序代码实现这个设计的。审查会上对照程序设计常见错误,分析审查这个程序。当发现时,记录错误,继续审查。,代码审查的方法,讨论:是由一些有经验的测试人员阅读程序文本及有关文档,对程序的结构与功能、数据的结构、
34、接口、控制流以及语法进行讨论和分析,从而揭示程序中的错误。走查:是由测试人员用一些测试用例沿程序逻辑运行,并随时记录程序的踪迹;然后进行分析,发现程序中的错误。(人工模仿计算机执行程序),7.3.3 计算机测试,模块的“计算机测试”在这里是指使用计算机系统对“模块”作为独立测试对象进行测试。由于模块并不是一个独立的程序,要运行它就必须为其开发驱动软件和(或)存根(桩)软件。模块测试的“驱动程序”“驱动程序”也就是一个“主程序”,它接收测试数据,把这些数据传送给被测试的模块,并且印出有关的结果。模块测试的“存根程序”存根程序(或称为“桩程序”)代替被测试的模块所调用的模块,也称为“虚拟子程序”。
35、它使用被它代替的模块的接口,可能做最少量的数据操作,印出对入口的检验或操作结果,并且把控制归还给调用它的模块。,单元测试的环境,例:对正文加工系统的“编辑”模块测试,测试任务:假定要测试正文加工系统中编号为3.0的“编辑”模块。驱动程序:TEST DRIVER说明必要的变量接收测试数据(字符串)调用被测模块“编辑”功能并且设置正文编辑模块的编辑功能(如“修改”、“添加”等)。存根程序:TEST STUB简化地模拟下层模块,完成具体的编辑功能(如“修改”CHANGE、“添加”APPEND等)。CHANGE和APPEND可以做成二个存根程序,也可只用一个存根程序模拟正文编辑模块的所有下层模块。,图
36、7.2 正文加工系统的层次图,计算机测试:评述,代码审查是人工测试,一次审查会上可以发现许多错误,但难以发现编码中的出错细节,一般用于模块的初步测试。用计算机测试的方法发现错误之后,通常需要先改正这个错误才能继续测试,因此错误是一个一个地发现并改正的。计算机测试需要开发驱动程序和存根程序,增加了一些系统开发工作量。可在集成测试中采用增量测试法来同时完成模块测试。人工测试和计算机测试互相补充,相辅相成,缺少其中任何一种方法都会使查找错误的效率降低。,7.4 集成测试,7.4.1自顶向下集成7.4.2自底向上集成7.4.3不同集成测试策略的比较7.4.4回归测试,集成测试概念及目标,集成测试把模块
37、按照设计要求组装起来的同时进行测试,目的是发现模块接口的错误。集成测试是测试和组装软件的系统化技术。集成测试的其主要目标是发现与接口有关的问题,如:数据穿过接口时可能丢失;一个模块对另一个模块可能由于疏忽而造成有害影响;把子功能组合起来可能不产生预期的主功能;个别看来是可以接受的误差可能积累到不能接受的程度;全程数据结构可能有问题等等。,模块组装成系统的方法,1.非渐增式测试方法非渐增式测试(整体拼装)先分别测试每个模块,再把所有模块按设计要求放在一起结合成所要的程序进行测试,最终得到要求的软件系统。2.渐增式测试把下一个要测试的模块同已经测试好的模块结合起来进行测试,测试完以后再把下一个应该
38、测试的模块结合进来测试。在组装过程中边连接边测试,以发现连接过程中产生的问题。通过增殖逐步组装成为要求的软件系统。这种每次增加一个模块的方法实际上同时完成单元测试和集成测试.在进行集成测试时普遍采用渐增式测试方法。,非渐增式测试,(a)软件结构(b)测试所有单个模块(c)测试整个系统,驱动,桩,渐增方式集成测试的策略,渐增方式把模块结合到程序中去时,有两种集成策略:自顶向下集成自底向上集成在实践中常采用混合的策略。,7.4.1 自顶向下集成,这种测试从“主控模块”开始,沿着程序结构的控制层次向下移动,逐渐将各个模块结合(组装)进来,指导所有底层模块。模块组装进来的顺序可有二种策略:“深度有限”
39、和“宽度(或称广度)优先”。自顶向下测试需要开发“存根程序”。,深度(宽度)优先组装,需要存根程序,图7.3 自顶向下结合,7.4.2 自底向上集成,这种测试从“底层模块”(即叶子模块)开始,向上移动,逐步将其上层模块组装进来,直到主控模块。同样,模块组装进来的顺序可有二种策略:“深度有限”和“宽度优先”。自底向上测试需要开发“启动模块”,自底向上组装,需要驱动程序,图7.4 自底向上结合,64,7.4.3 回归测试,任何成功的测试都会发现错误,而且错误必须被改正。每当改正软件错误的时候,软件配置的某些成分(程序、文档或数据)也被修改了。回归测试就是用于保证由于调试或其他原因引起的变化,不会导
40、致非预期的软件行为或额外错误的测试活动。即:回归测试是指重新执行已经做过的测试的某个子集,以保证修改变化没有带来非预期的副作用。回归测试集(已执行过的测试用例的子集)包括下述3类不同的测试用例:(1)检测软件全部功能的代表性测试用例;(2)专门针对可能受修改影响的软件功能的附加测试;(3)针对被修改过的软件成分的测试。,7.5 确认测试,7.5.1确认测试的范围7.5.2软件配置复查7.5.3Alpha和Beta测试,66,7.5 确认测试,确认测试也称为验收测试,它的目标是验证软件的有效性。确认(validation):指的是为了保证软件确实满足了用户需求而进行的一系列活动。验证(verif
41、ication):指的是保证软件正确地实现了某个特定要求的一系列活动。有效性:如果软件的功能和性能如同用户所合理期待的那样,软件就是有效的。需求分析阶段产生的软件需求规格说明书,准确地描述了用户对软件的合理期望,因此是软件有效性的标准,也是进行确认测试的基础。,67,7.5.1 确认测试的范围,确认测试必须有用户积极参与,或者以用户为主进行。用户应该参与设计测试方案,使用用户界面输入测试数据并且分析评价测试的输出结果。确认测试通常使用黑盒测试法。应该仔细设计测试计划和测试过程,测试计划包括要进行的测试的种类及进度安排,测试过程规定了用来检测软件是否与需求一致的测试方案。通过测试和调试要保证软件
42、能满足所有功能要求,能达到每个性能要求,文档资料是准确而完整的,此外,还应该保证软件能满足其他预定的要求(例如,安全性、可移植性、兼容性和可维护性等)。,68,7.5.2 软件配置复查,确认测试的一个重要内容是复查软件配置。软件配置指软件需求规格说明、软件设计规格说明、源代码等。复查的目的是保证软件配置的所有成分都齐全,质量符合要求,文档与程序完全一致,具有完成软件维护所必须的细节,而且已经编好目录。除了按合同规定的内容和要求,由人工审查软件配置之外,在确认测试过程中还应该严格遵循用户指南及其他操作程序,以便检验这些使用手册的完整性和正确性。必须仔细记录发现的遗漏或错误,并且适当地补充和改正。
43、,69,7.5.3 Alpha和Beta测试,Alpha测试由用户在开发者的场所进行,并且在开发者对用户的“指导”下进行测试。开发者负责记录发现的错误和使用中遇到的问题。该测试是在受控的环境中进行的。Beta测试由软件的最终用户们在一个或多个客户场所进行。Beta测试是软件在开发者不能控制的环境中的“真实”应用。用户记录在Beta测试过程中遇到的一切问题(真实的或想像的),并且定期把这些问题报告给开发者。接收到在Beta测试期间报告的问题之后,开发者对软件产品进行必要的修改,并准备向全体客户发布最终的软件产品。,70,如何实施测试?,关键技术-设计测试方案。测试方案-包括:具体的测试目的,应该
44、输入的测试数据和预期的结果。通常又把测试数据和预期的输出结果称为测试用例。其中最困难的问题是设计测试用例的输入数据。不同的测试数据发现程序错误的能力差别很大,为了提高测试效率降低测试成本,应该选用高效的测试数据。因为不可能进行穷尽的测试,选用少量“最有效的”测试数据,做到尽可能完备的测试就更重要了。,71,测试方案哪一种好呢?,设计测试方案的基本目标是,确定一组最可能发现某个错误或某类错误的测试数据。现已经研究出许多设计测试数据的技术,这些技术各有优缺点,没有哪一种是最好的,更没有哪一种可以代替其余所有技术;同一种技术在不同的应用场合效果可能相差很大,因此,通常需要联合使用多种设计测试数据的技
45、术。,7.6 白盒测试技术,7.6.1逻辑覆盖1.语句覆盖2.判定覆盖3.条件覆盖4.判定/条件覆盖5.条件组合覆盖6.点覆盖7.边覆盖8.路径覆盖7.6.2控制结构测试1.基本路径测试2.条件测试3.循环测试,73,7.6.1 逻辑覆盖,逻辑覆盖-是以程序内部的逻辑结构为基础的设计测试用例的技术。(1)语句覆盖(2)判定覆盖(3)条件覆盖(4)判定/条件覆盖(5)条件组合覆盖(6)点覆盖(7)边覆盖(8)路径覆盖,74,逻辑覆盖测试的5种标准,弱强,75,1.语句覆盖,使程序中每个语句至少执行一次。,开始,(A1)AND(B=0),(A=2)OR(X1),返回,X=X/A,X=X+1,F,F
46、,T,T,a,b,d,c,e,只需设计一个测试用例:输入数据:A=2,B=0,X=4 即达到了语句覆盖。,语句覆盖是最弱的逻辑覆盖(如:AND 写成 OR,X1 写成 X 1,查不出来),76,2、判定覆盖(分支覆盖),使每个判定的真假分支都至少执行一次。,开始,(A1)AND(B=0),(A=2)OR(X1),返回,X=X/A,X=X+1,F,F,T,T,a,b,d,c,e,可设计两组测试用例:A=3,B=0,X=3 可覆盖c、d分支 A=2,B=1,X=1 可覆盖b、e分支 两组测试用例可覆盖所有判定的真假分支,判定覆盖仍是弱的逻辑覆盖,只覆盖了全部路径的一半。,77,3、条件覆盖,使每个
47、判定的每个条件的可能取值至少执行一次。,开始,(A1)AND(B=0),(A=2)OR(X1),返回,X=X/A,X=X+1,F,F,T,T,a,b,d,c,e,满足条件:T1,T1,T2,T2 T3,T3 T4,T4,第一判定表达式:设条件 A1 取真 记为T1 假 T1 条件 B=0 取真 记为T2 假 T2第二判定表达式:设条件 A=2 取真 记为T3 假 T3 条件 X1 取真 记为T4 假 T4,78,测试用例 通过 满足的 覆盖A B X 路径 条件 分支1 0 3 abe T1,T2,T3,T4 b,e2 1 1 abe T1,T2,T3,T4 b,e 两个测试用例覆盖了四个条件
48、八种可能取值。未覆盖c、d分支,不满足判定覆盖的要求.条件覆盖不一定包含判定覆盖 判定覆盖也不一定包含条件覆盖,(A1)AND(B=0),(A=2)OR(X1),X=X/A,X=X+1,F,F,T,T,a,b,d,c,e,79,4.判定/条件覆盖,选取足够多的测试用例,使判断中的每个条件的所有可能取值至少执行一次,同时每个判断本身的所有可能判断结果至少执行一次.,开始,(A1)AND(B=0),(A=2)OR(X1),返回,X=X/A,X=X+1,F,F,T,T,a,b,d,c,e,满足条件:T1,T1,T2,T2 T3,T3 T4,T4,80,测试用例 通过 满足的条件 覆盖A B X 路径
49、 分支2 0 4 ace T1,T2,T3,T4 c,e1 1 1 abd T1,T2,T3,T4 b,d能同时满足判定、条件两种覆盖标准的取值,5、条件组合覆盖所有可能的条件取值组合至少执行一次 A1,B=0 A1,B0 A1,B=0 A1,B0 A=2,X1 A=2,X1 A2,X1 A2,X1,测试用例 通过 满足的 覆盖A B X 路径 条件 分支2 0 4 ace T1,T2,T3,T4 c,e2 1 1 abe T1,T2,T3,T4 b,e1 0 2 abd T1,T2,T3,T4 b,d1 1 1 abd T1,T2,T3,T4 b,d,(A1)AND(B=0),(A=2)OR
50、(X1),X=X/A,X=X+1,F,F,T,T,a,b,d,c,e,82,以上根据测试数据对源程序语句检测的详尽程度,简单讨论了几种逻辑覆盖标准。在上面的分析过程中常常谈到测试数据执行的程序路径,显然,测试数据可以检测的程序路径的多少,也反映了对程序测试的详尽程度。从对程序路径的覆盖程度分析,能够提出下述一些主要的逻辑覆盖标准。,语句覆盖法评述,83,6.点覆盖图论中点覆盖的概念定义如下:如果连通图G的子图G是连通的,而且包含G的所有结点,则称G是G的点覆盖。在第5章中已经讲述了从程序流程图导出流图的方法。在正常情况下流图是连通的有向图。满足点覆盖标准要求选取足够多的测试数据,使得程序执行路