第2章软件测试基础软件测试在软件开发中的地位越来越重要。软件测试是目前用来验证软件是否能够完成所期望的功能的唯一有效的方法,其总目标是充分利用有限的人力和物力资源,高效率、高质量地完成测试。本章重点:●软件测试的基本概念●软件测试的关键问题●软件测试的复杂性与经济性●软件测试原则●停止测试的标准2.1软件测试的基本概念尽管软件测试是一门技术很强的学科,但正确认识测试的目的十分重要,测试目的决定了测试方案的设计。如果我们的目的是要证明程序中没有隐藏的故障,那我们就会不自觉地回避可能出现故障的地方,设计出一些不易暴露故障的测试方案,从而使程序的可靠性受到极大的影响。如果我们的目标是要证明程序中有错,那就会力求设计出最能暴露故障的测试方案。2.1.1软件测试的目的2.1.2软件测试的定义IEEE在软件工程标准术语中给软件测试下的定义是:“使用人工或自动手段来运行或测定某个系统的过程,其目的在于检验它是否满足规定的需求或是弄清预期结果与实际结果之间的差别”。该定义包含了两方面的含义:1)是否满足规定的需求2)是否有差别1.不同时期关于软件测试的定义如果有差别,说明设计或实现中存在故障,自然不满足规定的需求。因此,这一定义非常明确地提出了软件测试以检验软件是否满足需求为目标。该定义指出测试时需要明确预期结果,然后将它们与实际发生的结果相比较,因此比较是测试的基础之一,确定预期输出是测试用例必不可少的一部分。一个测试用例由两部分组成:对程序输入数据的描述和由这些输入数据应产生的正确结果的精确描述。2.1.2软件测试的定义2.1.2软件测试的定义对测试人员,测试的最好定义是:测试是为了发现故障而执行程序的过程。这一定义非常明确地提出了软件测试以发现故障为目的。强调正确定义软件测试的另一方面是正确使用“成功”和“失败”这两个词。一般来说,“成功”表示达到了某种目的,而“失败”则表示令人失望或事不如愿。但在测试中,由于查不出故障的测试浪费了大量的时间和人力,因此使用“成功”这个词就显得不够恰当了。事实证明,发现故障是一个有价值的工作。发现故障的测试是成功的测试.2.1.2软件测试的定义●测试1)测试是一种活动,在该活动中一个系统或组成部分在特定条件下被运行,结果被观察或记录,并对该系统或组成部分的某些方面进行评估。2)测试是一个或多个测试用例的集合。2.1.2软件测试的定义●测试用例1)测试用例是为特定的目的而开发的一组测试输入、执行条件和预期结果。2)测试用例是执行的最小实体。●测试步骤测试步骤详细说明了如何设置、执行和评估特定的测试用例。2.关于软件测试的一些常用术语需求规格说明设计编码测试故障分类故障隔离故障清除故障故障故障事故修复图2-1一个测试生命周期需求规格说明设计编码测试故障分类故障隔离故障清除故障故障故障故障事故修复需求规格说明设计编码测试故障分类故障隔离故障清除故障故障故障事故修复图2-1一个测试生命周期故障故障故障需求规格说明设计编码测试故障分类故障隔离故障清除故障故障故障事故修复图2-1一个测试生命周期需求规格说明设计编码测试故障分类故障隔离故障清除故障故障故障故障事故修复需求规格说明设计编码测试故障分类故障隔离故障清除故障故障故障事故修复图2-1一个测试生命周期故障故障故障故障产生的原因2.1软件测试的基本概念软件测试主要涉及5方面的问题:谁来执行测试?测试什么?什么时候测试?怎样进行测试?测试停止的标准是什么?2.1.3软件测试涉及的关键问题2.1.3软件测试涉及的关键问题软件测试主要涉及5方面的问题:谁来执行测试?测试什么?什么时候测试?怎样进行测试?测试停止的标准是什么?一个软件产品的开发通常涉及开发者和测试者两种角色。开发者通过开发而形成产品,例如分析,设计,编码,调试或者文档编制。测试者通过测试来检测产品中存在的缺陷,包括根据特定的目的设计测试用例,构造测试,执行测试以及评估测试结果等。2.1.3软件测试涉及的关键问题软件测试主要涉及5方面的问题:谁来执行测试?测试什么?什么时候测试?怎样进行测试?测试停止的标准是什么?显然,表现在程序中的故障,并不一定是编码所引起的。即使针对源程序进行测试,所发现故障的根源也可能在开发前期的各个阶段。实际上,软件需求分析、设计和实施阶段是软件故障的主要来源,因此,需求分析、概要设计、详细设计以及程序编码等各个阶段所得到的文挡,包括需求规格说明分析、概要设计规格说明、详细设计规格说明以及源程序,都应成为软件测试的对象。2.1.3软件测试涉及的关键问题软件测试主要涉及5方面的问题:谁来执行测试?测试什么?什么时候测试?怎样进行测试?测试停止的标准是什么?测试的另一个极端是每天都进行测试,一旦软件的每个模块开发出来之后就对它们测试,这样显然又会延缓早期开发的进度。测试开始的时间越早,测试执行的越频繁,所带来的整个软件开发成本的下降就会越多。2.1.3软件测试涉及的关键问题软件测试主要涉及5方面的问题:谁来执行测试?测试什么?什么时候测试?怎样进行测试?测试停止的标准是什么?规范说明一个软件要做什么,而程序实现则规定了软件应怎样做。对软件进行测试就是根据软件的功能规范说明和程序实现,利用介绍的各种测试方法,生成有效的测试用例,对软件进行测试。2.1.3软件测试涉及的关键问题软件测试主要涉及5方面的问题:谁来执行测试?测试什么?什么时候测试?怎样进行测试?测试停止的标准是什么?从现实和经济的角度来看,对软件进行完全测试是不可能的。因为无法判断当前查出的故障是否为最后一个故障,所以决定什么时候停止测试是一件很最困难的事。实用的测试停止的标准应该基于以下几个因素:●成功地采用了具体的测试用例设计方法。●每一类覆盖的覆盖率。●故障检测率(即每一单元测试时间内检测出的故障数)低于指定的限度。基于故障检测数量的标准必须注明故障严重性程度。●检测出故障的具体数量(估计存在的故障总量的比率)或消耗的具体时间。2.1.3软件测试涉及的关键问题2.1.4软件测试与软件质量保证测试能帮助确保一个产品满足需求,但测试并不是质量保证。在许多组织中,软件质量保证部门通常负责开发测试计划和执行系统测试,也可能会对开发过程中的测试进行监测和保留统计数据。测试是任何质量保证过程中必需的但不是所有的部分。测试在确保质量方面的主要贡献在于它能发现那些在一开始就应该能够避免的错误。软件质量保证部门从事的是那些用来防止和去除软件缺陷的活动,负责制订为了生产出更好的软件而应该遵守的标准,包括定义为理解设计意图而创建的各种文档的类型,指导项目活动的过程以及量化决议结果的方法等。2.2软件故障故障(fault)、失效(failure)、错误(error)、缺陷(defect)、隐错(bug)、过失(mistake)、异常(anomaly)等术语常用来描述软件失败时的现象。我们采用IEEE制定的标准术语。●错误(error)——人是会犯错误的。一个很接近的同义词是过失(mistake)。过失是人犯下的,是人做的一件错事或人为产生的一个不正确结果。●故障(fault)——故障是错误的结果(可能导致失效)。更精确地说,故障是错误的表现。与故障很接近的一个同义词是缺陷(defect),●失效(failure)——故障(例如崩溃)引起的结果(表现)。2.2.1故障定义与任何事物一样,软件也有一个从孕育、诞生、成长到衰亡的生存过程,通常称为软件生存周期。包括制定计划、需求分析、设计、程序编码、测试运行维护六个阶段。2.2软件故障2.2.2软件故障分类软件开发经过制定开发计划,进行需求分析、软件设计阶段之后,才能进入编写程序阶段,程序编写完之后还必须经过大量的测试工作才能交付使用。因此,编写程序只是软件开发过程的一个阶段。在典型的软件开发工程中,编写程序所需的工作量只是软件开发全部工作量的20%左右。2.2软件故障2.2.2软件故障分类2.2软件故障2.2.2软件故障分类软件故障有多种分类方法:可以以故障出现的开发阶段来划分,以失效产生的后果来划分,以解决难度来划分,以不解决会产生的风险来划分,等等。图2-2给出了软件故障的大致分布情况。56%需求27%设计7%代码10%其它图2-2软件故障分布56%需求27%设计7%代码10%其它56%需求27%设计7%代码10%其它图2-分析软件故障分布情况,有助于将测试的主要精力更好地集中到最有价值的地方,以改进软件测试过程,提高软件测试的效率。2.2软件故障2.2.2软件故障分类严重程度举例说明1.轻微2.中等3.使人不悦4.影响使用5.严重6.较严重7.很严重8.无法忍受9.灾难性10.传染性强拼写错误等误导或重复信息等被截断的名称等有些情况没有处理丢失功能不正确的处理经常出现严重的错误数据库破坏系统停机影响其它系统停机表2-1按严重程度分类的软件故障2.2软件故障2.2.2软件故障分类其它类型的软件故障●软件需求故障●输入/输出故障●逻辑故障●计算故障●接口故障●数据故障由于人的主观认识常常难以完全符合客观现实,与工程密切相关的各类人员之间的通信和配合也不可能完美无缺。在软件生存周期的每个阶段都不可避免地会产生差错,并且前一阶段的故障自然会导致后一阶段相应的故障,因此,故障会积累起来。此外,后一阶段的工作是前一阶段工作结果的进一步具体化,因此,前一阶段的一个故障可能会造成后一阶段中出现几个故障。软件故障不仅有积累效应,还有放大效应。2.2软件故障2.2.3软件故障的修复图2-3形象地表示了故障的积累和放大效应。2.2软件故障初始需求正确的规格说明不正确的说明正确的设计不正确的设计不正确说明的设计正确编码错误编码不正确设计的编码不正确说明的编码正确功能可修复的故障不可修复潜伏的故障的故障图2-3软件故障的积累和放大效应初始需求正确的规格说明不正确的说明正确的设计不正确的设计不正确说明的设计正确编码错误编码不正确设计的编码不正确说明的编码正确功能可修复的故障不可修复潜伏的故障的故障初始需求正确的规格说明不正确的说明正确的设计不正确的设计不正确说明的设计正确编码错误编码不正确设计的编码不正确说明的编码正确编码错误编码不正确设计的编码不正确说明的编码正确功能可修复的故障不可修复潜伏的故障的故障正确功能可修复的故障不可修复潜伏的故障的故障图2-3软件故障的积累和放大效应所有的错误都是要付出代价的。统计资料表明,在软件开发的不同阶段进行改动需要付出的代价完全不同。后期改动的代价比前期进行相应修改要高出2~3个数量级。2.2软件故障2.2.3软件故障的修复2.3测试的复杂性与经济性黑盒测试是一种常用的软件测试方法,在应用这种方法设计测试用例时,我们把被测程序看成是一个打不开的黑盒,测试人员在不考虑程序内部结构和内部特性的情况下,只根据需求规格说明书,设计测试用例,检查程序的功能是否按照规范说明的规定正确地执行。如果希望利用黑盒测试方法查出软件中所有的故障,只能采用穷举输入测试。即把所有可能的输入全部都用作测试输入使用。2.3测试的复杂性与经济性例如,要对MicrosoftWindows计算器程序进行测试。要穷举地测试这个Windows计算器程序,实际上就得给出无穷多个测试用例。黑盒穷举测试不现实。2.3测试的复杂性与经济性白盒测试是否可以做到穷举测试呢?白盒测试又称结构测试或基于程序的测试。该方法将被测对象看作一个打开的盒子,允许人们检查其内部结构。测试人员根据程序内部的结构特性,设计、选择测试用例,检测程序的每条路径是否都按照预定的要求正确地执行。然而,程序的独立路径数目可能是个天文数字。独立逻辑路径的数目,相当于从A点走到B点的所有独立路径数,是520+519+…+51,其中5是贯穿循环体的路径数。如果每5分钟可以写出、执行并验证一个测试用例,那么测试完所有路径大概要花10亿年。AB≥20次图2-5一个简单程序的控制流程图AB≥20次AB≥20次图2-一个简单程序的控制流程图AB≥20次AB≥20次图2-5一个简单程序