第12章软件测试软件测试是对软件规格说明、软件设计和编码的最全面也是最后的审查。通过软件测试,可以发现软件中绝大部分潜伏的错误,从而可以大大提高软件产品的正确性、可靠性,进而可显著提高产品质量。统计表明,软件测试工作往往占软件开发总工作量的40%以上。甚至3~5倍以上。第12章软件测试本章将介绍:软件测试的基本知识;软件测试的常用方法和技术;软件测试的过程;软件的调试与排错技术;软件测试的工具。第12章软件测试12.1软件测试的基本知识12.2软件测试技术12.3软件测试过程12.4调试12.5测试工具12.1软件测试的基本知识软件测试是执行程序发现并排除程序中潜伏的错误的过程。软件测试是软件投入运行前,对软件需求分析、设计、实现的强有力的最终审查。12.1.1软件测试的目标与原则测试用例——为了进行有效的测试而设计的输入数据和预期的输出结果数据。Myers在其软件测试著作中对软件测试的目标提出以下观点:①软件测试是为了发现错误而运行程序的过程;②一个好的测试用例能够发现至今尚未发现的错误;③一个成功的测试是发现了至今尚未发现的错误的测试。测试原则①应尽早和不断地进行软件“测试”,即将这种“测试”贯穿于软件开发的各个阶段,坚持各个阶段的技术评审,以便尽早地发现和预防错误。②测试用例中,不仅要选择合理的输入数据,还要选择不合理的输入数据。③在开发各阶段应事先分别制定出相应的测试计划,在测试开始后应严格执行,防止随意性。④对发现错误较多的程序模块,应进行重点测试。Pareto指出,测试发现错误的80%集中在20%的模块中。发现错误较多的模块质量较差,需重点测试,并要测试是否引入了新的错误。测试原则⑤避免程序员测试自己的程序。测试用例的设计应有第三方参与。对于大型软件的测试,一般的做法是:设计者与测试者共同完成单元测试任务,而综合测试由专门的测试机构负责,有时其中也可以有设计者参加⑥用穷举测试是不现实的,一般通过设计测试用例,充分覆盖所有条件或所有语句即可。⑦长期妥善保存测试计划、测试用例、出错统计和有关的分析报告。12.1.2软件测试的步骤图14-1-1测试步骤部件代码部件代码单元测试单元测试单元测试…部件代码集成测试功能测试性能测试验收测试安装测试设计规格说明系统功能需求其他软件需求用户需求规格说明用户环境集成后的模块功能系统验证,生效的软件被接受的系统在使用中的系统测试后的模块12.1.2软件测试的步骤在本书中,从软件工程的角度:将单元测试与详细设计对应起来,即在详细设计阶段就应制定出单元测试计划;而集成测试又称为综合测试,可以把概要设计和集成测试对应起来,在概要设计阶段就可以制定集成测试计划;将功能测试、性能(行为)测试、验收测试统称为验收测试(也称确认测试),与软件系统需求分析阶段对应起来,在需求分析阶段就应制定出验收准则和验收测试计划,验收测试应提交经用户确认的软件产品;最后,将软件、硬件等要素构成一个完整的基于计算机的系统,再进行系统测试,使系统测试与系统定义相对应,即在系统定义阶段就应制定系统测试计划。12.1.2软件测试的步骤图14-1-2软件工程的开发与测试的关系系统工程需求分析概要设计设计、编码单元测试集成测试验收测试系统测试12.1.3测试阶段的信息流图14-1-3测试阶段的信息流测试评价排错可靠性模型软件配置测试配置测试结果错误错误统计预期结果正确的程序可靠性预测12.1.3测试阶段的信息流测试的输入流有软件配置和测试配置。软件配置由需求规格说明、设计说明、源代码等组成;测试配置包括测试计划、测试用例(其中包括预期的结果)、测试工具等组成。测试结果评价经常发现严重的错误并需要修改软件,则软件的质量和可靠性一定不高,需要进一步测试;如果测试所发现的错误不多且易于改正,软件功能看起来也较完善,则需考虑两种可能:1)软件质量和可靠性确实令人满意;2)测试不全面,很可能还潜伏着严重错误;如果测试过程没有发现任何错误,则很有可能是测试配置不合理。12.1.4软件测试的常用方法1.静态测试静态测试是采用人工检测和计算机辅助静态分析的方法对程序进行检测。人工检测是指靠人工走查程序或评审软件。这种走查与评审主要针对编码的质量和软件开发各个阶段的文档,特别是总体设计和详细设计阶段的错误。能发现30%~70%的逻辑设计和编码错误。计算机辅助静态分析是指利用静态分析软件工具对程序进行静态分析,主要检测变量是否用错、参数是否匹配、循环嵌套是否有错、是否有死循环和永远执行不到的死代码等等。同时,它还可对程序的特性进行分析。12.1.4软件测试的常用方法2.动态测试动态测试是指事先设计好一组测试用例,然后通过运行程序来发现错误。动态测试有两种测试方法:黑盒测试;白盒测试。12.1.4软件测试的常用方法黑盒测试,又称为功能测试——把被测的程序模块看成一个黑匣子,即完全不考虑程序的内部结构和处理过程,测试仅在程序的接口上进行。白盒测试——把被测的程序看成一个透明的白匣子,即完全了解程序的内部结构和详细的处理过程,测试是在程序的内部结构上进行。即要求针对每一条逻辑路径都要设计测试用例,检查每一个分支和每一次循环的情况。穷举测试是不现实的。如上图,设循环体应执行30次,循环体中有4个独立的分支,则最多有430≈1018个逻辑路径,假设每运行一个测试用例平均花费1毫秒,则需花费3千多万年。一般选用少量最有效的测试用例,以便覆盖每一个条件、每一个路径和每一个语句,从而以最少的代价发现尽可能多的错误。开始结束12.1.5软件测试中常见的错误类型按照错误的影响和造成的后果进行分类,可分为:较小错误,中等错误,较严重错误,严重错误,非常严重的错误,最严重的错误。按照软件生存周期各个阶段分类,可分为:问题定义错误、需求分析规格说明错误、设计错误、编码错误等等。这里重点介绍一种按照错误的性质和范围进行分类的方法,可以将错误分为如下几类:按照错误的性质和范围进行分类1.功能错误①需求规格说明错误。主要是指其中有错误、多余或遗漏的功能,有二义性或自相矛盾。②设计实现错误。设计或实现的功能不是规格说明或用户所要求的功能。按照错误的性质和范围进行分类2.系统错误①外部接口错误。如与打印机的接口错误。②内部接口错误。指各程序模块间的联系存在错误。如输入/输出、数据保护、子程序访问等。③硬件结构错误。如错误地理解I/O指令、中断处理、设备启动和初始化等而引起的错误。④软件结构错误。由于软件结构不合理或不清晰所引起的错误。往往在系统满载时才能发现。⑤操作系统错误。该类错误是由于不了解操作系统而引起的,操作系统本身也有错误。⑥控制与顺序错误。包括事件的时间顺序不正确、等待一个不可能发生的事件等等。⑦资源管理错误。既资源使用不当。资源死锁等。按照错误的性质和范围进行分类3.加工错误(算法错误)①计算与操作错误。指计算、函数求值和一般操作过程中的错误。②初始化错误。如忘记了初始化工作区、数据区,错误地对循环变量赋初值,不正确的初始化等等。③局部控制和次序错误。如遗漏路径、不可达到的代码段、循环嵌套或终止条件不正确、死循环等等。④逻辑错误。如多分支、判断条件不正确等。按照错误的性质和范围进行分类4.数据错误①动态数据错误。②静态数据错误。静态数据指直接或间接地出现在程序或数据库中的数据,其内容和格式都是固定的。因此在内容或格式上都可能存在错误。③数据内容错误。是指由于内容被破坏或被错误地解释而造成的错误。④数据结构错误。包括数据结构说明错误和数据结构使用错误。⑤数据属性错误。数据属性是指数据内容的含义或语义,如整数、字符等。数据属性错误是指对数据属性的错误解释和错误使用而导致的错误。按照错误的性质和范围进行分类5.代码错误代码错误主要包括语法错误、键入错误、对语句的理解错误等。例如,Myers(1976)指出,美国第一个去金星的太空任务的失败是由于在一个Fortrando循环中缺少一个逗号。12.2软件测试技术12.2.1白盒测试白盒测试的原则是:①保证程序中每一独立的路径至少执行一次;②保证所有判定的每一个分支至少执行一次;③保证每个判定表达式中每个条件的所有可能结果至少出现一次;④保证每一循环都在边界条件和一般条件至少各执行一次;⑤验证所有内部数据结构的有效性。几种典型的白盒测试技术1.逻辑覆盖逻辑覆盖是指设计测试用例对程序的内部分支逻辑结构进行部分或全部覆盖的技术。1)语句覆盖2)判定覆盖3)条件覆盖4)判定/条件覆盖5)条件组合覆盖6)路径覆盖逻辑覆盖1)语句覆盖—使程序中的每个语句至少执行一次。令x=2,y=0,z=4作为测试数据,程序执行路径为abcde,使语句段1和2各执行一次,实现了语句覆盖。它不能检测所有判定条件的错误。比如,错把z1写成了z1,则上述测试用例就无法检测出来了。(x1)AND(y=0)(x=2)OR(z1)语句段1语句段2开始结束TTFFabcde2)判定覆盖——分支覆盖判定覆盖是指设计足够多的测试用例,使每个判定的每种可能结果都至少出现一次,也就是使每个判定的每个分支都至少执行一次。可以设计如下两组数据以满足判定覆盖:x=3,y=0,z=1(通过路径abce);x=2,y=1,z=2(通过路径acde)。判定覆盖必然满足语句覆盖。覆盖程度仍然不高。比如,错把z1写成了z1,则上述测试用例仍无法检测出来。因为它只覆盖了全部路径的一半。判定覆盖可以推广到多分支情况。(x1)AND(y=0)(x=2)OR(z1)语句段1语句段2开始结束TTFFabcde3)条件覆盖条件覆盖是指设计足够的测试用例,使每个判定表达式中的每个条件的每种可能值都至少出现一次。如图,共有4个条件:x1,y=0,x=2,z1。条件覆盖要求设计测试用例,覆盖第一个判定表达式的x1,y=0,x≤1,y≠0等各种结果,并覆盖第二个判定表达式的x=2,z1,x≠2,z≤1等各种结果。(x1)AND(y=0)(x=2)OR(z1)语句段1语句段2开始结束TTFFabcde3)条件覆盖设计如下两组测试用例,可以满足条件覆盖的标准:x=2,y=0,z=3(覆盖x1,y=0,x=2,z1,通过路径abcde);x=1,y=1,z=1(覆盖x≤1,y≠0,x≠2,z≤1,通过路径ace)。(x1)AND(y=0)(x=2)OR(z1)语句段1语句段2开始结束TTFFabcde3)条件覆盖但是,如果设计如下一组测试用例:x=1,y=0,z=3(覆盖x≤1,y=0,x≠2,z1,通过路径acde);x=2,y=1,z=1(覆盖x1,y≠0,x=2,z≤1,通过路径ace)。虽满足条件覆盖,但不满足语句覆盖和判定覆盖。(x1)AND(y=0)(x=2)OR(z1)语句段1语句段2开始结束TTFFabcde4)判定/条件覆盖它是指设计足够的测试用例,使得判定表达式中的每个条件都取到所有可能的值(即满足条件覆盖),并使每个判定表达式也都取到所有可能的判定结果(即满足判定覆盖)。4)判定/条件覆盖x=2,y=0,z=3(覆盖x1,y=0,x=2,z1,通过路径abcde);x=1,y=1,z=1(覆盖x≤1,y≠0,x≠2,z≤1,通过路径ace)。(x1)AND(y=0)(x=2)OR(z1)语句段1语句段2开始结束TTFFabcde5)条件组合覆盖条件组合覆盖是指设计足够的测试用例,使得每个判定表达式中条件的各种可能值的组合都至少出现一次。这是一种较强的逻辑覆盖。如图,两个判定表达式中含有4个条件,共有8种组合:①x>1,y=0;②x>1,y≠0;③x≤1,y=0;④x≤1,y≠0;⑤x=2,z>1;⑥x=2,z≤1;⑦x≠2,z>1;⑧x≠2,z≤1。(x1)AND(y=0)(x=2)OR(z1)语句段1语句段2开始结束TTFFabcdex=2,y=0,z=3;覆盖条件组合①和⑤,通过路径abcde;x=2,y=1,z=1;覆盖条件组合②和⑥,通过路径acde;x=0,y=0,z=3;覆盖条件组合③和⑦,通过路径acd