1.2 软件测试基础理论
1.2.1 软件测试定义与基本问题
1.软件测试定义
软件测试就是在软件开发和投入运行前的各阶段,对软件需求分析、设计规格说明和程序编码等过程的阶段性和最终复查。它是软件质量保证的关键步骤。通常对软件测试的定义有两种描述。
定义1:软件测试是为了发现错误而执行程序的过程。
定义2:软件测试是根据软件开发各阶段的规格说明和程序的内部结构而精心设计的一批测试用例(即输入数据及其预期的输出结果),并利用这些测试用例运行程序以及发现错误的过程,即执行测试步骤。
测试:所谓测试的含义,首先是一项活动,在这项活动中某个系统或组成的部分将在特定的条件下运行,结果将被观察和记录,并对系统或组成部分进行评价。测试活动有两种结果:找出缺陷和故障,或显示软件执行正确。测试是一个或多个测试用例的集合。
测试用例:测试用例是为特定目的而设计的一组测试输入、执行条件和预期的结果;它是执行测试的最小实体。
测试步骤:测试步骤中详细规定了如何设置、执行、评估特定的测试用例。
2.软件测试基本问题
一个软件生命周期包括:制订计划、需求分析定义、软件设计、程序编码、软件测试、软件运行、软件维护、软件停用等8个阶段。软件测试贯穿于整个软件生命周期。
(1)明确测试根本目的。软件测试的目的是保证软件的质量。软件质量的内涵包括:正确性、可靠性、可维护性、可读性(文档、注释)、结构化、可测试性、可移植性、可扩展性、用户界面友好性、易学、易用、健壮性等。保证软件质量主要有两条途径:除了通过贯彻软件工程各种有效的技术方法和措施使得尽量在软件开发期间减少错误,其次就是通过测试活动来发现和纠正软件错误,因此,软件测试是软件质量的重要保证。
对一个软件系统做的测试越多,就越能确保它的正确性。软件测试在确保软件质量方面的主要贡献在于它能发现那些在一开始就应当避免的错误,软件质量保证的使命首先是避免错误。
(2)确认测试的对象。软件测试不仅仅是对程序的测试,而且贯穿于软件定义和开发的整个过程。因此,软件开发过程中产生的需求分析、概要设计、详细设计以及编码等各个阶段所得到的文档,包括需求规格说明、概要设计规格说明、详细设计规格说明以及源程序,都是软件测试的对象。
(3)建立测试生命周期。软件从开发设计、运行、直到结束使用的全生命周期中,主要横跨两个测试历程。因此,软件测试的生命周期也包括在软件的生命周期之中。从大的方面可以分为软件生产阶段的测试活动和软件运行维护阶段的测试活动。如图1.3所示为软件测试生命周期模型。
图1.3 一个测试生命周期模型
其中:①、②、③可能引入故障,或导致其他阶段的故障,为第一阶段;
④测试发现事故,为第二阶段;
⑤、⑥、⑦清除故障,为第三阶段;
⑦在故障排除的过程中有可能使以前正确执行的程序出现错误,引入了新的故障。
(4)制定和实施测试策略。这项工作有以下四方面:
第一,测试由谁来执行。通常软件产品的开发设计中有开发者和测试者两种角色。开发者通过开发而形成产品,如以上所列的分析、设计、编码调试或文档编制等。测试者通过测试来检测产品中是否存在缺陷,包括根据特定目的而设计的测试用例、构造测试、执行测试和评价测试结果等。通常的做法是开发者(机构或组织)负责完成自己代码的单元测试,而系统测试则由一些独立的测试人员或专门的测试机构进行。
第二,测试什么。测试经验表明,通常表现在程序中的故障,并不一定是由编码所引起的。它可能是在详细设计、概要设计阶段,甚至是需求分析阶段的问题所致。即使对源程序进行测试,所发现故障的根源也可能是在开发前期的某个阶段。要排除故障、修正错误也必须追溯到前期的工作。事实上,软件需求分析、设计和实施阶段是软件故障的主要来源。
第三,什么时候进行测试。测试是一个与开发并行的过程,还是在开发完成某个阶段任务之后的活动或者是开发结束后的活动,即模块开发结束之后可以进行测试,也可以推迟在各模块装配成为一个完整的程序之后再进行测试。开发经验证明,随着开发的不断深入,没有进行测试的模块对整个软件的潜在破坏作用就越明显。
第四,怎样进行测试。软件“规范”说明了软件本身应该达到的目标,程序“实现”则是一种对应各种输入如何产生输出结果的算法。换言之,规范界定了一个软件要做什么,而程序实现则规定了软件应该怎样做。对软件进行测试就是根据软件的功能规范说明和程序实现,利用各种测试方法,生成有效的测试用例,对软件进行测试。
1.2.2 软件测试的基本理论
1.软件测试的目标
软件测试是以发现故障或缺陷为目标,是为发现故障而执行程序的过程。软件测试的目的不是为了显示程序是正确的,而是要证明程序中有故障存在,测试的目标是最大可能地找出最多的错误。测试时应从软件包含有缺陷和故障这个假定去实施测试活动,并从中发现尽可能多的问题。实现这个目的的关键是怎样合理地设计出最能暴露出问题的测试用例。在设计测试用例时,要着重考虑那些易于发现软件错误的方法策略和具体技术。
综上所述,软件测试的目标包括以下三点:
(1)测试是程序的执行过程,目的在于发现错误,不能证明程序的正确性,仅限于处理有限的情况。
(2)检查系统是否满足需求,这也是测试的期望目标。
(3)一个好的测试用例在于发现还未曾发现的错误,成功的测试是发现了错误的测试。
2.软件测试的原则
(1)尽早和及时的测试应作为软件开发人员的座右铭,测试应当从软件产品开发初始阶段即开始。
(2)测试用例应当由测试数据和与之对应的预期结果两部分组成。
(3)在程序提交测试后,应当由专门的测试人员进行测试,避免由程序设计者自行检查程序。
(4)测试用例应包括合理的输入条件和不合理的输入条件。
(5)严格执行测试计划,排除测试的随意性。
(6)充分注意测试当中的群体现象,测试经验表明,约一半(47%)的错误仅与系统中4%的程序模块有关。
(7)应对每一个测试结果做全面的检查。
(8)保存测试计划、测试用例、出错统计和最终分析报告,为维护工作提供充分的资料。
3.测试在软件开发各阶段的作用
(1)项目规划阶段:负责从单元测试到系统测试的整个测试阶段的监控。
(2)需求分析阶段:确定测试需求分析、系统测试计划的制定,评审后成为管理项目。测试需求分析是对产品生命周期中测试所需求的资源、配置、每阶段评判通过的规约;系统测试计划则是依据软件的需求规格说明书,制定测试计划和设计相应的测试用例。
(3)详细设计和概要设计阶段:确保集成测试计划和单元测试计划完成。
(4)编码阶段:由开发人员对其负责部分的代码进行测试。在项目较大时,由专人进行编码阶段的测试任务。
(5)测试阶段(单元测试、集成测试、系统测试等):依据测试用例进行测试,并提交相应的测试状态报告和测试结束报告。
4.测试信息的流程
测试信息流程如图1.4所示,测试过程中需要有下列三类输入。
图1.4 测试信息流程
(1)软件配置:软件需求规格说明,软件设计规格说明,源代码等。
(2)测试配置:测试计划,测试用例,测试驱动程序等。
(3)测试工具:为提高测试效率,采用测试工具支持测试工作。测试数据自动生成程序、驱动测试的测试数据库等。
5.软件测试的周期性
软件生命周期由制订计划、需求分析定义、软件设计、程序编码、软件测试、软件运行、软件维护、软件停用8个阶段构成;而软件测试的周期性是:测试→改错→再测试→再改错,这样一个循环的过程,如图1.5所示。
6.软件测试停止依据
软件测试因要受到成本或其他方面条件的制约,测试最终是要终止的,通常有5类终止测试的标准或依据。
第一类标准:测试超过了预定时间则终止测试。这类标准不能用来衡量软件测试的质量。
第二类标准:执行了所有的测试用例,但并没有发现故障,则终止测试。这类标准对测试并无好的指导作用,相反却有可能默认测试人员没有编出更好的、能暴露出更多故障的测试用例。
第三类标准:使用特定的测试用例设计方案作为判断测试终止的基础。这类标准仍然是一个主观的衡量尺度,无法保证测试人员准确、严格地使用某种测试方法。这类标准只是给出了测试用例设计的方法,并非确定的目标,并且这类标准只适用于某些测试阶段。
第四类标准:正面指出终止测试的具体要求,即终止测试的标准可定义为查出某一预定数目的故障,如规定发现并修改了多少个故障就可停止测试。对系统测试的标准是,发现并修改若干个故障或至少系统要运行一定时间,如几个月等。使用第四类标准需求解决两个问题:第一个问题是如何知道将要查处的故障数目,另一个问题是可能会过高地估计了故障的总数目。解决问题的途径是根据过去的经验和软件开发业界常用的一些平均估值方法(关于这方面的详细论述请查阅有关资料)。
第五类标准:根据单位时间内查出故障的数量决定是否终止测试。这个标准看似容易,但实际操作中要用到较多直觉和判断。通常使用图表说明某测试阶段中单位时间检查出的故障数量,通过分析图,确定应继续测试还是终止测试。
图1.5 软件测试的周期性
1.2.3 软件测试和缺陷修复的代价
软件通常需要靠有计划、有条理地开发。从需求、设计、编制测试一直到交付用户公开使用后的整个过程中,都有可能产生和发现缺陷。随着整个开发过程的时间推移,在需求阶段没有被修正的错误问题或缺陷有可能不断扩大和蔓延到设计阶段、编码和测试阶段,甚至达到维护阶段,如图1.6所示。
图1.6 开发前期存在错误造成后期开发阶段的扩大和蔓延
而且越是到软件开发后期,更正缺陷或修复问题费用越大,呈几何级数增长。在编写产品说明书早期发现的软件缺陷,如果费用按人民币计算,则同样的软件缺陷若在软件编制完成再开始测试的时候才发现,则费用将要上升十倍,如果软件缺陷是在发售后由用户发现则修正费用则可能达到上百倍。如图1.7所示是软件缺陷在不同阶段发现时修改的费用增长示意图。
图1.7 软件缺陷在不同阶段发现时修复的费用增长示意图
这个过程说明了在软件开发过程的早期发现软件的缺陷,修正缺陷的费用会很低,反之代价是很大的。例如,前述的“狮子王动画书”的软件缺陷案例,其根本的问题是软件无法兼容当时流行的各种家庭用PC平台。假如早在编写产品说明书时,即考虑过有几种家用PC平台在市场中较为流行,并在说明书上写明需要在某种机型的配置上怎样设计和测试,所花费的人力和财力则并不大,也不会产生等到产品发售完毕,到达用户手中后出现大量的软件兼容性问题,而造成被动的局面。在这一软件缺陷的恶性事件中,迪斯尼公司最终支付了客户投诉,产品退货、更换软件,以及新一轮的该软件产品设计、调试、修改和测试过程,不仅多耗费了大量费用,还承载了市场声誉的严重损失。
1.2.4 软件测试策略与技术概要
软件测试策略是指测试将按照怎样的思路和方式进行,而软件测试技术则是指在测试实施过程当中将运用的具体测试方法。
1.软件测试策略
通常,软件测试策略需要确定测试组织、测试策划、测试过程(测试部署)、测试管理等重大问题,以及这些环节、过程及步骤如何实现,将采用何种措施来保证。它包含了对测试总体的设计与部署,过程与管理,成本与效率,技术与运用等诸多方面。例如,针对测试部署,过程如下:制定测试计划(回答为何做、如何做、谁来做、何时做、何时结五个问题)→搭建测试环境→执行测试计划→分析测试结果→检查是否达到测试目的→编写测试报告,如图1.8所示。
关于软件测试策略的详细过程叙述,在本书第2章将做详细说明。
图1.8 测试部署过程
2.软件测试的类别与技术
软件测试根据测试的目标、阶段、方法将采用不同的技术。软件测试技术是指在测试过程当中所采用的具体测试方法。实际测试中,常用的具体策略和技术方法如下:
(1)若按照软件测试用例的设计方法而论,软件测试可分为白盒测试法和黑盒测试法。
(2)若按照软件测试针对是否执行软件的程序而论,软件测试又可分为静态测试和动态测试两类。
(3)若按照软件测试在具体测试时是否运用测试工具或程度不同而采用的模式而论,软件测试可分为手工测试技术和自动化测试技术两种。
(4)若按照软件架构与设计是否采用了面向对象技术而论,软件测试又可分为传统的面向过程的测试方法和面向对象的测试方法。
(5)若按照将一个软件产品(项目或系统)中局部与整体的组成关系和功能而论,软件测试分为单元测试、集成测试、系统测试(功能测试、性能测试、安全性测试、回归测试、确认性测试以及验收测试)等。
(6)若按照软件系统的架构或设计是否在网络环境下运行、在单机环境下运行、为一个特定环境下的应用(如嵌入式系统等)而论,软件测试又分别针对C/S(特定形式B/S)应用系统的测试(包括网络性能测试、数据库性能测试、服务器性能测试、客户端性能测试等),嵌入式系统测试等。
(7)若针对软件测试过程的管理而论,软件测试还包含测试管理技术。
(8)软件测试的具体细节技术,如针对软件自动化测试中的测试脚本生成和运用技术等。
关于软件测试的各种技术的具体方法,本书第2章将详细说明。
3.α测试与β测试
α测试与β测试也属于软件测试的范畴,但它是基于非专业测试人员进行的测试,主要是由软件的用户参与的测试活动。
(1)α测试。α测试是由一个用户在开发环境下进行的测试,也可以是开发机构内部的用户在模拟实际操作环境下进行的测试。软件在一个自然设置状态下使用。开发者坐在用户旁边,随时记下错误情况和使用中的问题。这是在受控制的环境下进行的测试。α测试的目的是评价软件产品的FLURPS(即功能、局域化、可使用性、可靠性、性能和支持),尤其注重产品的界面和特色。α测试人员是除产品的开发人员之外首先见到产品的用户,他们提出的功能和修改意见有较重要的价值。α测试可以从软件产品编码结束之时开始,或在模块(子系统)测试完成之后开始,也可以在确认测试过程中产品达到一定的稳定和可靠程序之后再开始。在进行测试之前,应事先准备好有关的手册(草稿)等文档。
(2)β测试。β测试是由软件的多个用户在一个或多个用户实际使用环境下进行的测试。这些用户是与软件开发者签订支持产品预发行合同的外部客户,要求用户使用该产品,并愿意返回有关错误信息给开发者。与α测试不同的是,开发者通常不在测试现场,因而β测试是在开发者无法控制的环境下进行的现场、实时、随机的应用。在β测试中,由用户记录使用中所遇到的所有问题,包括真实的和主观认定的,并定期向开发者报告。开发者在综合用户的报告之后,决定并修改软件,最后将软件交付全体用户使用。β测试主要衡量产品的FLURPS,着重于产品的支持性,包括文档、客户培训和支持产品生产能力。β测试在α测试达到一定可靠程度时开始进行,由于它处在整个测试的最后阶段,不能期望这时再发现主要问题。同时,软件产品的所有手册文档也应在此阶段完成。由于β测试的主要目标是测试可支持性,所以β测试应尽可能由主持产品发行的人员进行管理。
4.测试技术发展趋势
当前,软件测试技术发展主要包括以下几个方面,并在实际软件测试工程当中运用。
(1)验证技术。软件验证的目的用于证明软件生命周期的各个阶段以及各阶段间的逻辑协调性和正确性。目前,软件验证技术还只适用于特殊用途的小型程序。
(2)静态测试分析技术。目前,软件测试正在逐渐地由向对程序代码的静态测试向高层开发产品的静态测试方向发展,如静态分析工具的产生。所谓静态分析工具是在不执行程序的情况下分析软件的特性。静态分析主要集中在需求文档、设计文档以及程序结构等方面,可以进行类型分析、接口分析、输入/输出规格说明分析,等等。
(3)测试数据的自动生成和选择。在测试数据的选择方面,主要是对测试用例进行选择,这对测试的成功与否有着重要的影响。这项技术主要从以下几方面对测试用例的质量进行把握。
①检测软件缺陷的有效性。
②测试用例的可重用性。通过重用测试用例,修改后即可对其他内容进行测试,减轻了测试用例编写工作负担。
③测试用例的执行、分析和调试是否经济。
④测试用例的可维护性,即每次软件修改后对测试用例的维护成本控制。
(4)集成化测试。这是软件测试技术的最新发展方向,主要的目标是研究如何实现软件测试的自动化过程以及相关的一系列内容。它将多种测试工具融为一体,合成为功能强大的测试工具。此外,还针对测试评估开发出了测试评估工具,用来评估程序结构元素被覆盖的程度,从而确定测试活动的充分性。