
1.5 软件测试的定义
在传统的制造业中,在产品生产过程中每一道工序结束时,都由质量人员进行检验,或由仪器自动进行检验。软件测试,简单地理解,就是对软件产品进行检验和验证,包括对软件阶段性产品和最终产品进行检验。如果要对软件测试有更全面的理解,这样的定义还不够,我们还需要从不同的角度对软件测试进行更为科学的、全面的定义。
1.5.1 基本定义的正反两面性
最早给软件测试下定义的是Bill Hetzel博士,在1973年给出了软件测试的第一个定义——软件测试就是为程序能够按预期设想那样运行而建立足够的信心。在1983年,他又将软件测试的定义修改为:“软件测试是一系列活动以评价一个程序或系统的特性或能力并确定是否达到预期的结果”,测试是对软件质量的度量。在上述两个定义中的“设想”和“预期的结果”可以被认为是用户的需求或者是产品功能设计。从Bill Hetzel的定义可以看出,测试是为了验证软件是否符合用户需求,即验证软件产品是否能正常工作,是正向思维,针对软件系统的所有功能点,逐个验证其正确性。
1983年,IEEE给软件测试下的定义是:“使用人工或自动的手段来运行或测定某个软件系统的过程,其目的在于检验它是否满足规定的需求或弄清预期结果与实际结果之间的差别”。这个定义和Bill Hetzel给出的定义比较接近,强调软件测试是为了检验软件系统是否满足(客户的)需求。随后,1990年,IEEE再次给出了软件测试的定义(IEEE/ANSI,1990 [Std 610.12- 1990])。
(1)在特定的条件下运行系统或构件,观察或记录结果,对系统的某个方面做出评价。
(2)分析某个软件项以发现现存的和要求的条件之差别(即错误),并评价此软件项的特性。
与正向思维相反的是逆向思维,即人们无法证明软件是正确的,只能认定软件是有错误的,然后去发现尽可能多的错误,以提高软件产品的质量。这种观点的代表人物是Glenford J. Myers(代表作《软件测试的艺术》),他还从人的心理学的角度论证,如果将“验证软件是工作的”作为测试的目的,非常不利于测试人员发现软件的错误。于是他于1979年给软件测试下了一个完全不同的定义:“测试是为发现错误而针对某个程序或系统的执行过程”。简单地说就是验证软件是“不工作的”,或者说是有问题的。从这个概念出发,一个成功的测试必须是发现缺陷的测试,不然就没有价值。这就如同一个病人(假定此人确有病),到医院做一项医疗检查,结果各项指标都正常,那说明该项医疗检查对于诊断该病人的病情是没有价值的,是失败的。概括起来,Myers给出了与测试相关的3个要点:
•测试是为了证明程序有错,而不是证明程序无错误;
•一个好的测试用例在于它能发现至今未发现的错误;
•一个成功的测试是发现了至今未发现的错误的测试。
基于“验证”的观点,主要是在设计规定的环境下运行软件的各项功能,将其结果与用户需求或设计结果相比较,如果相符则测试通过;如果不相符则视为不通过,进行修正,直至所有的功能通过验证。基于“找错”的观点,强调测试人员发挥主观能动性,用逆向思维方式,不断思考人们容易犯错误的地方(如误解、不良习惯造成的,数据边界)和系统的薄弱环节,试图破坏系统,从而发现系统中所存在的问题。图1-3对上述两种看似对立的观点进行了总结。

图1-3 软件测试定义的对立性(两面性)
这两种观点都有一定的局限性,正向思维有利于界定测试工作的范畴,促进与开发人员协作,但可能降低测试工作的效率。而逆向思维有利于测试人员主观能动性的发挥,可以使测试人员发现更多的问题,但也容易使测试人员忽视用户的需求,使测试工作存在一定的随意性和盲目性。实际上,测试可以看作这两者的统一,既要尽可能地、快速地发现问题,加快测试的进程;又能对实现的各项功能进行验证,保证测试的完整性和全面性。
1.5.2 服从于用户需求——V&V
前面讨论软件测试,是验证软件能否正常工作,并设法找出软件不能工作的地方,着重是从正向思维还是反向思维来考虑,但忽视了一个基本点,那就是基于什么来判断软件是能正常工作还是不能正常工作的?所以在软件测试时,必须建立判断的基准,也就是判断软件是否存在缺陷的依据。判断软件是否存在缺陷的基本依据是软件的用户需求,软件功能特性就是为了满足用户需求,不能满足用户需求的功能是有缺陷的。从这一点来看,测试要服从于用户需求,以用户需求为依据,来对产品进行检验。

DO-178C文档
但是,软件测试不能靠用户来完成,还必须由软件开发组织的测试人员来完成,所以我们要为软件建立相应的质量标准和软件设计规格说明书(Spec)。软件规格说明书是对用户需求的描述,是对实现的功能特性的说明,从而使软件设计、编程的人员知道要完成哪些功能,要将软件做成什么样子。所以,软件测试就是检验开发人员是否按照规格说明书来构造产品的,所构造的产品是否和规格说明书一致。
V&V代表Verification和Validation,即“验证”和“有效性确认”。软件测试被看作就是执行这两项任务,软件测试可以被定义为“验证”和“有效性确认”两项活动构成的整体。
(1)“验证”是检验软件是否已正确地实现了产品规格书所定义的系统功能和特性。验证过程提供证据,表明软件相关产品与所有生命周期活动的要求(如正确性、完整性、一致性、准确性等)相一致。相当于,以软件规格说明书为标准进行软件测试的活动。
(2)“有效性确认”是确认所开发的软件能满足用户真正需求的活动。因为软件规格说明书本身就可能存在问题,这些问题是无法通过“验证”活动来发现的,必须通过“确认”活动来发现问题,即一切从客户的观点出发,正确理解客户的需求,敢于怀疑需求定义和设计中不合理的东西,发现需求定义和产品设计中的各种问题。“确认”活动主要通过各种软件评审活动来实现,包括让客户参加评审、测试活动。
从以上内容可以看出,软件测试不仅要通过运行软件程序或软件系统来进行检验,而且要对软件相关文档,特别是需求定义和设计规格说明书等进行评审,以确认这些文档所描述的内容都是客户所需要的。这就说明,Myers明显受到传统的“软件开发瀑布模型”的影响,早期所给出的测试定义——“程序测试是为了发现错误而执行程序的过程”是片面的、不足的,这样就限制了软件测试活动,将需求和设计阶段产生的问题留到编程之后去发现、去解决,其结果将造成设计、编程的部分或全部返工,给软件开发带来巨大的劣质成本。实际上,我们也清楚知道,软件不等于程序或软件包,软件应当包括软件开发过程中产生的文档,软件是程序、文档和数据构成的一个集合或系统。
V&V将软件测试扩展到用户需求、设计等早期阶段,也符合软件测试的最基本原则:测试越早执行,对项目越有利,其项目进度越容易控制,其成本也越低。将软件测试扩展到需求、设计阶段,即将“需求评审、设计评审、代码评审”归为软件测试。
(1)需求评审:检查软件产品的需求定义和用户实际需求是否一致,即需求文档(包括use case、user story)是否客观、准确、清晰地描述了业务需求、用户需求等。通过需求评审,能够发现需求文档中存在的问题,包括描述存在的二义性、丢失的需求、不可测试性等,从而能够尽早修正需求定义中存在的问题。
(2)设计评审:检查软件系统的设计(如设计文档)与事先定义的需求是否一致,检查系统是否满足系统功能和非功能性需求,检查系统设计是否合理,是否存在单点失效问题、不可测试性等问题,及早纠正系统设计问题。
(3)代码评审:检查代码的逻辑运算、算法和其他处理等是否正确,还要检查代码是否符合编程规范,包括变量命名、格式、注释等。代码检查可以通过研发人员来完成,也可以通过工具进行代码分析和检查。
这意味着软件测试不再是编程之后的一个阶段,而是贯穿整个软件生命周期的活动。这样,软件测试不仅包含了动态测试,而且也包含了静态测试。
•动态测试是通过运行程序来发现软件系统中的问题。这种测试是在程序运行过程中将缺陷发现出来,具有动态性,所以称为动态测试。
•静态测试主要活动是评审,即通过对需求、设计、配置、程序和其他各类文档的审查来检验相应内容是否满足用户的需求。不需要运行程序,测试对象属于静态的。
概括地说,测试可以看作“验证”和“有效性确认”的统一,以客户的需求为基准,参照设计规格说明书,不仅对程序进行检验,而且要对软件产品的各种文档进行评审,从而更早地发现软件中存在的各种缺陷,降低软件开发成本,全面提高软件质量。
Testing和Verification关系的不同观点
(DO-178C/ED-12C)
我们这里强调的软件测试,或者说,在软件企业中常见的工作是开发工作和测试工作,不容易见到其他软件质量活动,所以把更多的责任给了测试,即
Test=Verification+Validation
但传统理论上,有另外一种说法,强调系统的验证活动,即:
Verification=Review + Analysis + Test
测试只是验证工作的活动之一,软件产品验证还包括评审、分析等活动。
•评审(Review):人工检查或借助简单工具来验证某个结果(需求文档、设计文档、代码等)符合特定的需求。
•分析(Analysis):通过所收集的数据分析来对一个完整的系统或子系统进行定量的(质量)评估。
•测试(Testing):通过精确测量(measurements)或操作,来证明或展示项目/产品满足需求。这里的测试主要是运行可执行程序而进行的动态测试,不涵盖“静态测试”。