《软件工程课件第5章结构化实现.ppt》由会员分享,可在线阅读,更多相关《软件工程课件第5章结构化实现.ppt(21页珍藏版)》请在三一办公上搜索。
1、结构化实现,第五章,2,主要内容,通常把编码和测试统称为实现。所谓编码就是把软件设计翻译成计算机可以理解的形式用某种程序设计语言书写的程序;测试的目的就是在软件投入生产性运行之前,尽可能多地发现软件中的错误。目前软件测试仍然是保证软件质量的关键步骤,它是对软件规格说明、设计和编码的最后复审。无论怎样强调软件测试的重要性和它对软件可靠性的影响都不过分。软件测试在软件生命周期中横跨两个阶段。通常在编写出每个模块之后就对它做必要的测试(称为单元测试),模块的编写者和测试者是同一个人,编码和单元测试属于软件生命周期的同一个阶段。在这个阶段结束之后,对软件系统还应该进行各种综合测试,这是软件生命周期中的
2、另一个独立的阶段,通常由专门的测试人员承担这项工作。大量统计资料表明,软件测试的工作量往往占软件开发总工作量的40%以上,在极端情况,测试那种关系人的生命安全的软件所花费的成本,可能相当于软件工程其他步骤总成本的35倍。因此,必须高度重视软件测试工作,绝不要以为写出程序之后软件开发工作就接近完成了,实际上,大约还有同样多的开发工作量需要完成。主要内容:编码,软件测试基础,逻辑覆盖,控制结构测试,墨盒测试技术,测试策略,调试,软件可靠性。,3,5.1 编码,5.1.1 选择程序设计语言总的说来。高级语言明显优于汇编语言,因此,除了在很特殊的应用领域(例如,对程度执行时间和使用的空间都有很严格限制
3、的情况;需要产生任意的甚至非法的指令序列;体系结构特殊的微处理机,以致在这类机器上通常不能实现高级语言编译程序),或者大型系统中执行时间非常关键的(或直接依赖于硬件的)一小部分代码需要用汇编语言书写之外,其他程序应该一律用高级语言书写。为了使程序容易测试和维护以减少生命周期的总成本,选用的高级语言应该有理想的模块化机制,以及可读性好的控制结构和数据结构。为了便于调试和提高软件可靠性,语言特点应该使编译程序能够尽可能多地发现程序中的错误;为了降低软件开发和维护的成本,选用的语言应该有良好的独立编译机制。上述这些要求是选择语言的理想标准,但是在实际选用语言时不能仅仅考虑理论上的标准,还必须同时考虑
4、实用方面的各种限制。,4,5.1.2 编码风格,源程序代码的逻辑简明清晰、易读易懂是好程序的一个重要标准,为了做到这一点,应该遵循下述规则。1.程序内部的文档所谓程序内部的文档包括恰当的标识符、适当的注解和程序的视觉组织等等。2.数据说明(即变量说明)数据说明的顺序应该标准化,使程序更容易阅读。3.语句构造构造语句时应该遵循的原则是,每个语句都应该简单而直接,不能为了提高效率而使程序变得过分复杂。多个语句不要写在同一行;避免复杂条件测试;减少对“非”条件测试;避免大量使用循环嵌套和条件嵌套;在表达式中少省略括号,可使运算次序清晰直观。,5,4.输入/输出在设计和编写程序时应该考虑下述有关输入/
5、输出风格的规则:对所有输入数据都进行检验;检查输入项重要组合的合法性;保持输入格式简单;使用数据结束标记,不要要求用户指定数据的数目;明确提示交互式输入的请求,详细说明可用的选择或边界数值;当程序设计语言对格式有严格要求时,应保持输入格式一致;设计良好的输出报表;给所有输出数据加标志。5.效率效率主要指处理机时间和存储器容量两个方面。虽然值得提出提高效率的要求,但是在进一步讨论这个问题之前应该记住三条原则:首先,效率是性能要求,因此应该在需求分析阶段确定效率方面的要求。软件应该像对它要求的那样有效,而不应该如同人类可能做到的那样有效。其次,效率是靠好设计来提高的。第三,程序的效率和程序的简单程
6、度是一致的。不要牺牲程序的清晰性和可读性来不必要地提高效率。,6,5.2 软件测试基础,5.2.1 测试目标G.Myers给出了关于测试的一些规则,这些规则也可以看作是测试的目标或定义:测试是为了发现程序中的错误而执行程序的过程;好的测试方案是极可能发现迄今为止尚未发现的错误的测试方案;成功的测试是发现了至今为止尚未发现的错误的测试。由于测试的目标是暴露程序中的错误,从心理学角度看,由程序的编写者自己进行测试是不恰当的。因此,在综合测试阶段通常由其他人员组成测试小组来完成测试工作。,7,5.2.2 黑盒测试和白盒测试,对于软件测试而言,黑盒测试法把程序看成一个黑盒子,完全不考虑程序的内部结构和
7、处理过程。也就是说,黑盒测试是在程序接口进行的测试,它只检查程序功能是否能按照规格说明书的规定正常使用,程序是否能适当地接收输入数据产生正确的输出信息,并且保持外部信息(如,数据库或文件)的完整性。黑盒测试又称为功能测试。与黑盒测试法相反,白盒测试法的前提是可以把程序看成装在一个透明的白盒子里,也就是完全了解程序的结构和处理过程。这种方法按照程序内部的逻辑测试程序,检验程序中的每条通路是否都能按预定要求正确工作。白盒测试又称为结构测试。,8,5.2.3 测试准则,为了能设计出有效的测试方案,软件工程师必须充分理解并正确运用指导软件测试的基本准则。主要的测试准则如下所述。所有的测试都应该能追溯到
8、用户需求。应该在测试开始之前的相当长时间,就制定出测试计划。把Pareto原理应用于软件测试。Pareto原理告诉我们,测试发现的错误中的80%很可能是由程序中20%的模块造成的。测试应该从“小规模”开始,并逐步进行“大规模”测试。穷举测试是不可能的。为了达到最佳的测试效果,应该由独立的第三方来从事测试工作。,9,5.2.4 流图,在设计测试方案时,往往需要仔细分析程序的控制流。为了突出表示程序的控制流,可以使用流图(也称为程序图)。流图仅仅描绘程序的控制流程,它完全不表现对数据的具体操作以及分支或循环的具体条件。在流图中用圆表示节点,一个圆代表一条或多条语句。程序流程图中的一个处理框序列和一
9、个菱形判定框,可以映射成流图中的一个节点。流图中的箭头线称为边,它和程序流程图中的箭头线类似,代表控制流。在流图中一条边必须终止于一个节点,即使这个节点并不代表任何语句(实际上相当于一个空语句)。由边和节点围成的面积称为区域,当计算区域数时应该包括图外部未被围起来的那个区域。图5.1 所示为把程序流程图映射成流图的方法,10,9,10,图5.1 把程序流程图映射成流图(左)程序流程图;(右)流图,11,5.3 逻辑覆盖,逻辑覆盖是设计白盒测试方案的一种技术。设计测试方案是测试阶段的关键技术问题。测试方案:包括具体的测试目的(例如,要测试的具体功能),应该输入的测试数据和预期的输出结果。测试用例
10、:通常指测试数据和预期的输出结果不同的测试数据发现程序错误的能力差别很大,为了提高测试效率降低测试成本,应该选用高效的测试数据。因为不可能进行穷尽的测试,选用少量“最有效的”测试数据,做到尽可能完备的测试就更重要了。有选择地执行程序中某些最有代表性的通路是对穷尽测试的唯一可行的替代办法。所谓逻辑覆盖是对一系列测试过程的总称,这组测试过程逐渐进行越来越完整的通路测试。测试数据执行(或叫覆盖)程序逻辑的程度可以划分成哪些不同的等级?从覆盖源程序语句的详尽程度分析,大致有以下一些不同的覆盖标准。,12,1.语句覆盖,语句覆盖的定义:选择足够多的测试数据,使被测程序中每个语句至少执行一次。测试数据A=
11、2,B=0,X=4可实现图5.4的语句覆盖,图5.4 被测试模块的流程图,13,2.判定覆盖判定覆盖又叫分支覆盖,它的含义是,不仅每个语句必须至少执行一次,而且每个判定的每种可能的结果都应该至少执行一次,也就是每个判定的每个分支都至少执行一次。测试数据例子:A=3,B=0,X=0;A=2,B=1,X=13.条件覆盖条件覆盖的含义是,不仅每个语句至少执行一次,而且使判定表达式中的每个条件都取到各种可能的结果。测试数据例子:A=2,B=0,X=4;A=1,B=1,X=14.判定/条件覆盖它的含义是,选取足够多的测试数据,使得判定表达式中的每个条件都取到各种可能的值,而且每个判定表达式也都取到各种可
12、能的结果。测试数据例子:A=2,B=0,X=4;A=1,B=1,X=15.条件组合覆盖条件组合覆盖是更强的逻辑覆盖标准,它要求选取足够多的测试数据,使得每个判定表达式中条件的各种可能组合都至少出现一次。,14,5.5 黑盒测试技术,黑盒测试着重测试软件的功能需求,也就是说,黑盒测试让软件工程师设计出能充分检查程序所有功能需求的输入条件集。黑盒测试并不能取代白盒测试技术,它是与白盒测试互补的方法,它很可能发现白盒测试不易发现的其他不同类型的错误。黑盒测试力图发现下述类型的错误:功能不正确或遗漏了功能;界面错误;数据结构错误或外部数据库访问错误;性能错误;初始化和终止错误。白盒测试在测试过程的早期
13、阶段进行,而黑盒测试主要用于测试过程的后期。黑盒测试故意不考虑程序的控制结构,而把注意力集中于信息域。,15,5.5.1 等价划分,等价划分是一种黑盒测试方法,这种方法把程序的输入域划分成数据类,据此可以导出测试用例。一个理想的测试用例能独自发现一类错误(例如,对所有字符数据的处理都不正确)。如果把所有可能的输入数据(有效的和无效的)划分成若干个等价类,则可以合理地做出下述假定:每类中的一个典型值在测试中的作用与这一类中所有其他值的作用相同。因此,可以从每个等价类中只取一组数据作为测试数据。这样选取的测试数据最有代表性,最可能发现程序中的错误。划分等价类需要经验,下述几条启发式规则可能有助于等
14、价类的划分。,16,几条划分等价类的启发式规则如果规定了输入值的范围,则可划分出一个有效的等价类(输入值在此范围内),两个无效的等价类(输入值小于最小值或大于最大值)。如果规定了输入数据的个数,则类似地也可以划分出一个有效的等价类和两个无效的等价类。如果规定了输入数据的一组值,而且程序对不同输入值做不同处理,则每个允许的输入值是一个有效的等价类,此外还有一个无效的等价类(任一个不允许的输入值)。如果规定了输入数据必须遵循的规则,则可以划分出一个有效的等价类(符合规则)和若干个无效的等价类(从各种不同角度违反规则)。如果规定了输入数据为整型,则可以划分出正整数、零和负整数等三个有效类。如果程序的
15、处理对象是表格,则应该使用空表,以及含一项或多项的划分出等价类以后,等价类设计测试方案时主要使用下面两个步骤。设计一个新的测试方案以尽可能多地覆盖尚未被覆盖的有效等价类,复重这一步骤直到所有有效等价类都被覆盖为止。设计一个新的测试方案,使它覆盖一个而且只覆盖一个尚未被覆盖的无效等价类,重复这一步骤直到所有无效等价类都被覆盖为止。,17,例子:假设有一个把数字串转变成整数的函数。运行程序的计算机字长16位,用二进制补码表示整数。这个函数是用PASCAL语言编写的,它的说明如下:functionstrtoint(dstr:shortstr):integer;函数的参数类型是shortstr,它的说
16、明是:type shortstr=array1.6of char;被处理的数字串是右对齐的,也就是说,如果数字串比六个字符短,则在它的左边补空格。如果数字串是负的,则负号和最高位数字紧相邻(负号在最高位数字左边一位)。考虑到PASCAL编译程序固有的检错功能,测试时不需要使用长度不等于6的数组做实在参数,更不需要使用任何非字符数组类型的实在参数。分析这个程序的规格说明,可以划分出如下等价类。(1)有效输入的等价类有 16个数字字符组成的数字串(最高位数字不是零);最高位数字是零的数字串;最高位数字左邻是负号的数字串。,18,(2)无效输入的等价类有 空字符串(全是空格);左部填充的字符既不是零
17、也不是空格;最高位数字右面由数字和空格混合组成;最高位数字右面由数字和其他字符混合组成;负号与最高位数字之间有空格。(3)合法输出的等价类有 在计算机能表示的最小负整数和零之间的负整数;零;在零和计算机能表示的最大正整数之间的正整数。(4)非法输出的等价类有 比计算机能表示的最小负整数还小的负整数;比计算机能表示的最大正整数还大的正整数。因为所用的计算机字长16位,用二进制补码表示整数,所以能表示的最小负整数是-32768,能表示的最大正整数是32767。,19,根据上面划分出的等价类,可以设计出下述测试方案(注意,每个测试方案由三部分内容组成)。16个数字组成的数字串,输出是合法的正整数。输
18、入:1,预期的输出:1 最高位数字是零的数字串,输出是合法的正整数。输入:000001,预期的输出:1 负号与最高位数字紧相邻,输出合法的负整数。输入:-00001,预期的输出:-1 最高位数字是零,输出也是零。输入:000000,预期的输出:0 太小的负整数。输入:-47561,预期的输出:“错误无效输入”太大的正整数。输入:132767,预期的输出:“错误无效输入”空字符串。输入:,预期的输出:“错误没有数字”字符串左部字符既不是零也不是空格。输入:1,预期的输出:“错误填充错”最高位数字后面有空格。输入:1 2,预期的输出:“错误无效输入”最高位数字后面有其他字符。输入:1 2,预期的输
19、出:“错误无效输入”负号和最高位数字之间有空格。输入:-12,预期的输出:“错误负号位置错”,20,5.5.2 边界值分析经验表明,处理边界情况时程序最容易发生错误。例如,许多程序错误出现在下标、纯量、数据结构和循环等的边界附近。因此,设计使程序运行在边界情况附近的测试方案,暴露出程序错误的可能性更大一些。使用边界值分析方法设计测试方案首先应该确定边界情况,这需要经验和创造性,通常输入等价类和输出等价类的边界,就是应该着重测试的程序边界情况。选取的测试数据应该刚好等于、刚刚小于和刚刚大于边界值。也就是说,按照边界值分析法,应该选取刚好等于、稍小于和稍大于等价类边界值的数据作为测试数据,而不是选
20、取每个等价类内的典型值或任意值作为测试数据。5.5.3 错误推测错误推测法在很大程度上靠直觉和经验进行。它的基本想法是列举出程序中可能有的错误和容易发生错误的特殊情况,并且根据它们选择测试方案。,21,5.6 测试策略,5.6.1 测试步骤从过程的观点考虑测试,在软件工程环境中的测试过程,实际上是顺序进行的三个步骤的序列。单元测试:着重测试每个单独的模块,以确保它作为一个单元来说功能是正确的。单元测试大量使用白盒测试技术,检查模块控制结构中的特定路径,以确保做到完全覆盖并发现最大数量的错误。集成测试:把模块装配(即集成)在一起形成完整的软件包。在装配的同时进行测试,因此称为集成测试。集成测试同时解决程序验证和程序构造这两个问题。在集成成测过程中最常用的是黑盒测试用例设计技术,当然,为了保证覆盖主要的控制路径,也可能使用一定数量的白盒测试。确认测试:在软件集成完成之后,还需要进行一系列高级测试。必须测试在需求分析阶段确定下来的确认标准,确认测试是对软件满足所有功能的、行为的和性能的需求的最终保证。在确认测试过程中仅使用黑盒测试技术。本章其它内容 略,