1第五章软件验证技术•5.1软件测试基础•5.2代码复审•5.3白盒测试•5.4黑盒测试•5.5单元测试•5.6集成测试•5.7确认测试•5.8系统测试•5.10调试•5.11小结2案例1“爱国者”在载赫蓝的失败1991年2月25日,一枚伊拉克飞毛腿导弹击中了沙特阿拉伯载赫蓝的一个军营,杀死了美国陆军第十四军需分队的28名士兵。政府调查指出该次失败归咎于导弹系统时钟内的一个软件错误。在此之前,爱国者导弹连在载赫蓝已经连续工作了100小时。至此,导弹的时钟已经偏差了三分之一秒,相等于600米的距离误差。软件中的错误案例2windows2000中文输入法的漏洞3软件验证1.定义:指通过检查和提供客观证据来表明软件已经满足规定的需求。2.作用:确保软件质量和降低软件成本的重要手段,关系到软件的整个生存周期3.软件验证的方式:测试证明4进行软件测试的原因任何工业产品在出厂前都要经过严格的质量检验,软件产品也不例外,在编码和调试完成之后,还需要进行严格的测试!软件开发的前面各阶段都已经采取了各种方法和技术进行质量保证,为什么还要进行软件测试?由于软件是一种高密集度的智力产品,比一般的硬件产品更复杂和难以控制。虽然在前阶段的开发过程中,采取了相应的措施,但仍然不可避免的会存在错误。还得提醒一下同学们:软件测试是很困难的,必须要有一整套的方法和技术进行指导。5测试测试分为静态测试和动态测试。静态测试(评审)动态测试定义对软件进行的分析和检查通过运行软件来检查其动态行为和运行结果的正确性。特点不执行程序运行程序执行时期软件开发的各阶段结束之前编码之后,软件开发的一个单独阶段测试对象软件开发的各种文档代码6测试测试是一项周期长、成本高的软件工程活动。一般的软件开发组织要将30%-40%的项目精力投入到测试之中,一些人命关天的软件其测试费用往往更高。测试无法保证测试后的软件不再有错误。测试过程中将产生下述基本文档:(1)测试计划:确定测试范围、方法和需要的资源等。(2)测试过程:详细描述与每个测试方案有关的测试步骤和数据,包括测试数据及预期的结果。(3)测试结果:把每次测试运行的结果写入文档,如果运行出错,则应产生问题报告,并且通过调试解决所出现的问题。7证明通过形式化的数学方法来确保软件正确性的活动。由于软件本身的复杂性,程序正确性证明还远未达到实用化的阶段。85.1软件测试基础软件测试的目的:以最少的代价发现软件分析、设计、编码中存在的各种不同类型的错误,从而提高软件质量,降低软件成本。9程序错误1、较小错误:只对系统输出有一些非实质性影响。如,输出的数据格式不合要求等。2、中等错误:对系统的运行有局部影响。如输出的某些数据有错误或出现冗余。3、较严重错误:系统的行为因错误的干扰而出现明显不合情理的现象。比如开出了0.00元的支票,系统的输出完全不可信赖。4、严重错误:系统运行不可跟踪,一时不能掌握其规律,时好时坏。5、非常严重的错误:系统运行中突然停机,其原因不明,无法软启动。6、最严重的错误:系统运行导致环境破坏,或是造成事故,引起生命、财产的损失。10软件测试的特点1、软件测试的开销大按照Boehm的统计,软件测试的开销大约占总成本的30%-50%。例如:APPOLLO登月计划,80%的经费用于软件测试。2、不能进行“穷举”测试只有将所有可能的情况都测试到,才有可能检查出所有的错误。但这是不可能的:例:程序P有两个整型输入量X、Y,输出量为Z在32位机上运行。所有的测试数据组(Xi,Yi)的数目为:232×232=264假设1毫秒执行1次,如要进行完全测试,共需5亿年。PXYZ11测试目的基于不同的立场,存在着两种完全不同的测试目的。从用户的角度出发,普遍希望通过软件测试暴露软件中隐藏的错误和缺陷,以考虑是否可以接受该产品。而从软件开发者的角度出发,则希望测试成为表明软件产品中不存在错误的过程,验证该软件已正确地实现了用户的要求,确立人们对软件质量的信心。12因此,他们会不自觉地选择那些导致程序失效概率小的测试用例,回避那些易于暴露程序错误的测试用例。同时,也不会着意去检测、排除程序中有可能包含的付作用,以致有可能潜含着诸如把边长为(0,0,0)的输入判成等边三角形的错误。13显然,这样的测试对完善和提高软件质量毫无价值。因为在程序中往往存在着许多预料不到的问题,可能会被疏漏,许多隐藏的错误只有在特定的环境下才可能暴露出来。如果不把着眼点放在尽可能查找错误这样一个基础上,这些隐藏的错误和缺陷就查不出来,会遗留到运行阶段中去。如果我们站在用户的角度,替他们设想,就应当把测试活动的目标对准揭露程序中存在的错误。在选取测试用例时,考虑那些易于发现程序错误的数据。14设计测试的目标是想以最少的时间和人力系统地找出软件中潜在的各种错误和缺陷。如果我们成功地实施了测试,就能够发现软件中的错误。测试的附带收获是,它能够证明软件的功能和性能与需求说明相符合。此外,实施测试收集到的测试结果数据为可靠性分析提供了依据。测试不能表明软件中不存在错误,它只能说明软件中存在错误。155.1.1测试观点GrenfordJ.Myers就软件测试目的提出的以下观点:1.测试是程序的执行过程,目的在于发现错误;2.一个好的测试用例在于能发现至今未发现的错误;3.一个成功的测试是发现了至今未发现的错误的测试。16测试的定义是为了发现程序中的错误而执行程序的过程,正确认识测试的目标是十分重要的,测试目标决定了测试方案的设计。如果为了表明程序是正确的而进行测试,就会设计一些不易暴露错误的测试方案;相反,如果测试是为了发现程序中的错误,就会力求设计出最能暴露错误的测试方案。17由于测试的目标是暴露程序中的错误,由程序的编写者自己进行测试是不恰当的。因此,在综合测试阶段通常由其他人员组成测试小组来完成测试工作。18此外,测试决不能证明程序是正确的。即使经过了最严格的测试之后,仍然可能还有没被发现的错误潜藏在程序中。换句话说,测试只能查找出程序中的错误,不能证明程序中没有错误。19测试阶段的基本任务:应该是根据软件开发各阶段的文档资料和程序的内部结构,精心设计一组“高产”的测试用例,利用这些用例执行程序,找出软件中潜在的各种错误和缺陷。205.1.2测试原则1.测试应“尽早地和不断地进行”。贯穿到软件开发的各个阶段。通过各阶段的评审,尽早解决错误,减少错误放大效应。212.较早确定测试计划,严格执行测试计划。测试计划:需求分析完成后就开始进行,测试之前应仔细考虑测试的项目,对每一项测试做出周密的计划。包括:测试目的、所测试软件的功能、输入和输出、测试内容、各项测试的进度安排、资源要求、测试工具、测试用例的选择、测试的控制方法和过程、系统组装方式、跟踪规程、调试规程以及评价标准等。测试用例:各种设计结果确定后即可开始。223.注意错误的群集现象和应用Pareto原则。群集现象是指—在测试过程中,发现错误比较集中的程序段,往往可能残留的错误数较多。因此必须注意这种群集现象,对错误群集的程序段进行重点测试,以提高测试投资的效率。Pareto原则—80%的错误来源于20%的程序模块。234.测试规模应从小到大。5.测试应由独立的第三方进行。程序员应尽可能避免测试自己编写的程序,程序开发小组也应尽可能避免测试本小组开发的程序。如果条件允许,最好建立独立的软件测试小组或测试机构。这点不能与程序的调试(debuging)相混淆。调试由程序员自己来做可能更有效。246.确保测试用例的完整性和有效性。测试用例的选择测试用例由两部分组成(测试输入数据和对应的预期输出结果)既有合理输入数据,也有不合理的输入数据用例既能检查应完成的任务,也能够检查不应该完成的任务。长期保存测试用例。7.保存所有测试用例和出错统计等信息,直至软件不用为止。255.1.3测试工具软件测试工具:一种测试软件,借助它可以提高软件测试工作的效率。软件测试的工作量通常占软件开发总工作量的40%—60%。作用:降低测试成本,提高测试质量和效率的途径。26测试工具的分类按工作方式分:静态分析工具动态测试工具按功能分:测试计划工具:支持制定测试计划;测试设计与开发工具:支持测试数据生成等;测试执行工具:支持特定的测试方法,支持回归测试等;测试评价工具:报告测试覆盖情况;测试管理工具:协助进行测试组织工作;其他辅助测试工具27几种典型的软件测试工具:静态分析测试软件动态分析测试软件测试数据自动生成程序文件比较程序285.1.4测试组织软件开发者:独立测试之前程序的单个模块:保证每个模块能完成详细设计的功能等;集成测试:保证每个模块能按总体设计的要求构成软件系统。独立测试小组:系统形成之后进行;需要开发人员协助;确保系统满足需求分析的要求和用户的意图。295.1.5测试与调试测试:查找错误症状的过程调试:查找错误症状的原因并改正错误的过程。结果:可能是查明错误原因并改正,也可能是未能发现错误原因,还有可能是引入新的错误。调试之后还应进一步测试和评价,以确保错误真正被消除且没有引入新的错误。30测试与调试的关系31输入信息有:软件配置:包括需求说明书,设计说明书,源程序清单测试配置:包括测试方案,测试计划,测试用例测试工具:支持测试的软件32输出信息:输出信息有修正软件的文件或预测可靠性或得出纠错后可交付使用的正确软件。这个测试的信息流是不断递归过程,也是相对有限的测试过程,而不是无限的过程。33包括:o软件配置:指被测试软件的文件,如软件需求规格说明书,软件设计说明书,源程序清单等文档。o测试配置:指测试计划,测试用例,测试程序等文档。o测试工具:是为提高测试效率而设计的支撑软件测试的软件。o测试评价:由测试出的错误迹象,分析找出错误的原因和位置,以便纠正和积累软件设计的经验。o纠错(调试):是指找到出错的原因与位置并纠错,包括修正文件直到软件正确为止。o可靠性模型:通过对测试出软件出错率的分析,建立模型,得出可靠的数据,指导软件的设计与维护。345.1.6动态测试步骤四个步骤:单元测试——编码阶段完成集成测试确认测试系统测试——指整个计算机系统(包括软件和硬件)的测试,可与系统的安装和验收结合进行。测试阶段完成35图5.2动态测试与软件开发各主要阶段的关系a用户需求需求规格说明书概要设计说明书详细设计说明书需求分析概要设计详细设计编码源代码单元测试集成测试确认测试系统测试问题产品虚线箭头表示测试未通过时所走的路线。错误发现越晚,改正工作量越大。36单元测试以“详细设计说明书”为准则,检查编码中出现的错误;集成测试以“概要设计说明书”为准则,检查详细设计和编码出现的错误;确认测试以“需求规格说明书”为准则,检查概要设计、详细设计和编码出现的错误;系统测试以“用户需求”为准则,检查需求分析、概要设计、详细设计和编码出现的错误。37测试与软件开发各阶段的关系软件开发过程是一个自顶向下,逐步细化的过程软件计划阶段定义软件作用域软件需求分析建立软件信息域、功能和性能需求、约束等软件设计把设计用某种程序设计语言转换成程序代码测试过程是依相反顺序安排的自底向上,逐步集成的过程。38测试与软件开发各阶段的关系39首先对每一个程序模块进行单元测试,消除程序模块内部在逻辑上和功能上的错误和缺陷。再对照软件设计进行集成测试,检测和排除子系统(或系统)结构上的错误。随后再对照需求,进行确认测试。最后从系统全体出发,运行系统,看是否满足要求。405.2代码复审执行时间:一般在程序通过编译及静态分析工具检查之后、动态测试之前。执行方式:人工测试,可由程序作者本人非正式的执行,由审查小组以开会的方式进行。特点:非常有效的程序验证技术,该方法能够有效地发现30%—70%的逻辑设计和编码错误。主要方法:代码会审、走查、办公桌检查。415.2.1代码复审内容检查编码实现是否完备、正确等。方法:复审过程中对照有关条例或错误检验表,查找程序在结构、功能、编码标准和风格等方面的错误