7.1软件测试基本概念
7.1.1软件产品质量的评定
软件产品质量是通过下面几点要求来进行测评的。
①可靠性:已部署的代码在执行过程中的预防故障(崩溃、挂起、内存丢失等)能力。
②功能:已部署的代码是否实现需求要求的功能。
③性能:在实际的操作特征(如负载、强度和长时间运行)条件下,已部署的代码以及时和可接受的方式执行和响应,并以可接受的方式继续运行。
7.1.2软件测试的目的
在软件投入运行前,对软件需求分析、设计规格说明和编码的最终复审,是软件质量保证的关键步骤。测试的目的就是以较少的用例、时间和人力找出软件中潜在的各种错误和缺陷,以确保系统的质量。主要体现为下面几点。
①确保产品完成了它所承诺或公布的功能,并且所有用户可以访问到的功能都有明确的书面说明。
②确保产品满足性能和效率的要求。使用起来系统运行效率低(性能低)或用户界面不友好、用户操作不方便(效率低)的产品不能说是一个有竞争力的产品。
③确保产品是健壮的和适应用户环境的。健壮性即稳定性,是产品质量的基本要求,尤其对于一个用于事务关键或时间关键的工作环境中的软件非常重要。
7.1.3测试和质量之间的关系
测试有助于提高软件的质量,但是提高软件的质量不能依赖于测试。测试与质量的关系很像在考试中“检查”与“成绩”的关系。学习好的学生,在考试时通过认真检查能减少因疏忽而造成的答题错误,从而“提高”考试成绩(取得他本来就该得的好成绩)。而学习差的学生,他原本就不会做题目,无论检查多么细心,也不可能提高成绩。所以说,软件的高质量是设计出来的,而不是靠测试修补出来的。
7.2测试的重要原则和规律
1.Good—Enough原则
Good—Enough原则就是一种权衡投入/产出比的原则。不充分的测试是不负责任的;而过分的测试则是一种资源的浪费,同样也是一种不负责任的表现。操作困难在于如何界定什么样的测试是不充分的,什么样的测试是过分的。目前状况唯一可用的答案是制定最低测试通过标准和测试内容,然后具体问题具体分析。
2.木桶原理
产品质量的关键因素是分析、设计和实现,测试应该是融于其中的补充检查手段,其他管理、支持,甚至文化因素也会影响最终产品的质量。应该说,测试是提高产品质量的必要条件,也是提高产品质量最直接、最快捷的手段,但决不是一种根本手段。反过来说,如果将提高产品质量的砝码全部押在测试上,那将是一个恐怖而漫长的灾难。
3.Bug的80—20原则
一般情况下,在分析、设计、实现阶段的复审和测试工作能够发现和避免80%的Bug,而系统测试又能找出其余Bug中的15%,最后的5%的Bug可能只有在用户的大范围、长时间使用后才会暴露出来。因为测试只能够保证尽可能多地发现错误,无法保证能够发现所有的错误。
4.其他
在很多组织中,软件测试占软件开发费用的30%~50%。但大多数人仍然认为,软件在交付之前没有进行充分的测试。这一矛盾根植于两个明显的事实。第一个,测试软件十分困难,因为给定的程序具有无数的不同行为方式。第二个,测试通常是在没有明确的方法,不采用必需的自动化手段和工具支持的情况下进行的。由于软件的复杂性,无法实现完全测试,但采用周密的方法和最新技术水平的工具可以明显提高软件测试的生产率和有效性。
对于如果失败将导致人员伤亡这类“安全至上”的系统(如空中交通管制系统、导弹制导系统或医用输送系统)来说,高质量的软件是系统成功的要素。对于典型的MIS系统来说,上述情况不是非常明显,但是,消除缺陷造成的影响将需要相当昂贵的代价。
在软件生命周期早期启动时就执行良好的测试,将明显降低完成和维护软件的开支。它还可以大大降低与部署质量低劣的软件相关的责任或风险,如用户的生产率低下、数据输入和计算错误,以及令人无法接受的功能行为。现在,许多MIS系统是“任务至上”的,也就是说当出现失败时,公司将无法正常运转并导致大量损失。例如:银行或运输公司。测试“任务至上”的系统时,必须使用“安全至上”的系统所采用的类似严格方法。
7.3测试的生命周期
在软件开发生命周期中,软件测试是通过迭代来不断加以完善的。在这种环境中,对于每个作为测试目标的工作版本来说,测试的生命周期都必须具有一种迭代的方法。针对每个工作版本执行的测试,都作出了增补和改进,用于后续阶段的回归测试。该方法表明它将导致在整个流程中重复进行测试,就像修订软件本身一样。这里没有一成不变的软件规约,也没有一成不变的测试。
测试是软件生命周期的一部分,它们应该同时开始。测试的设计开发过程与正在构建的应用程序一样复杂和艰巨。如果未能尽早开始测试或者不够完善,就会导致需要在开发时间表上附加一个长时间的测试和错误修正时间表,这将有违迭代开发的初衷。此外,测试计划和设计活动可以揭示应用程序定义中的故障和缺陷。这些问题越早得以解决,对整个时间表造成的影响就越小。评价过程中发现的问题可以在本次迭代解决,也可以留待下次迭代解决。通过核实已经实施的需求来评测迭代的完全程度,是评价的主要任务之一。
7.4测试过程中涉及的文档规范及测试流程
测试过程中所涉及的文档主要包括:测试计划、测试规范、测试案例、测试报告、Bug报告。
1.测试计划(Test Plan)
制订一个完整、规范的测试计划对每一个测试管理人员来说是非常重要的。当然,根据每一个测试管理人员具体任务的不同,他们的测试计划也会有所差异。测试计划和产品开发紧密相关,由好几个部分组成,所有的大型商业软件都需要有完整的测试计划,需要具体到每一个步骤,并且每一个部分都必须符合规范要求。
2.测试规范(Test Specification)
所谓测试规范,是指每一个在测试计划中确定的产品领域所写的,用来描述该领域中的测试需求的文档。在编写测试规范之前,需要参考项目经理写的产品规范,以及开发人员写的开发计划。但每个开发人员的习惯都不一样,对于有写开发计划习惯的人员来说,写测试规范和测试计划就很容易了。另外,每一个领域都应该有一份详细的测试规范,所以还需要参照测试计划,因为测试规范的内容要与该计划相吻合。
3.测试案例(Test Case)
所谓测试案例,是指描述如何测试某一个领域的文档,这些文档符合测试规范中的需求说明。在开发测试案例之前,必须具备一份正确的项目经理规范和一份详细的测试规范。在开发测试案例时,第一个案例一定是根据规范中定义的测试而开发的。在运行的过程中根据测试反馈信息,我们可能会发现未考虑的新问题,这就需要不断地添加测试案例。另外,当发现新的Bug时,也必须添加新的测试案例,这样就可以免去回归测试。
4.测试报告(Test Report)
在测试的过程中,测试管理人员会定期汇报测试进展。通常测试管理人员以测试报告的形式向整个产品开发部门报告测试的结果及发现的Bug。撰写测试报告的目的是为了让整个产品开发部门了解产品开发的进展情况,以使Bug能够迅速得到修正。
5.Bug报告(Bug Report)
测试人员在测试过程中,如果发现了Bug,就应该及时向开发人员报告。通常测试人员是以Bug报告的形式向开发人员报告所发现的问题。撰写Bug报告的目的是为了使问题能够迅速得到解决。因此测试人员的Bug报告撰写的好坏会直接影响到开发人员的修改质量。Bug报告写得不好,开发人员就不能有效地从测试报告中得到关于Bug的正确详细信息,从而导致Bug修正被推迟甚至根本没有得到修正。
7.5测试的分类和策略
7.5.1按阶段分类
在软件交付周期的不同阶段,通常需要对不同类型的目标应用测试。这些阶段是从测试小的构件(单元测试)到测试整个系统(系统测试)不断向前发展的。
1.单元测试
单元测试在迭代的早期实施,侧重于核实软件的最小可测试元素。单元测试通常应用于实施模型中的构件,核实是否已覆盖控制流和数据流,以及构件是否可以按照预期工作。
2.集成测试
执行集成测试是为了确保当把实施模型中的构件集成起来执行用例时,这些构件能够正常运行。测试对象是实施模型中的一个包或一组包。要集成的包通常来自于不同的开发组织。集成测试将揭示包接口规约中不够完全或错误的地方。
3.系统测试
当将软件作为整体运行或实施明确定义的软件行为子集时,即可进行系统测试。这种情况下的目标是系统的整个实施模型。
4.验收测试
验收测试是部署软件之前的最后一个测试操作。验收测试的目的是确保软件准备就绪,并且可以供最终用户用于执行软件的既定功能和任务。
7.5.2按内容分类
1.性能测试
(1)基准测试
测试比较新的或未知测试对象与已知参照标准(如现有软件或评测标准)的性能。
(2)争用测试
核实测试对象对于并发操作(数据记录、内存等)的请求的处理是否可以接受。
(3)性能配置
核实在操作条件保持不变的情况下,测试对象在使用不同配置时其性能是否可以接受。
(4)负载测试
核实在保持配置不变的情况下,测试对象在不同操作条件(如不同用户数、事务数等)下性能行为的可接受性。
(5)强度测试
核实测试对象性能行为在异常或极端条件(如资源减少或用户数过多)之下的可接受性。
2.白盒与黑盒
“白盒测试”是指开发人员从程序内部对上述内容进行测试,而“黑盒测试”是指独立的测试人员从程序外部对上述内容进行测试。
黑盒测试用例设计包括如下内容。
(1)等价类划分
划分等价类—确立测试用例—设计用例。
(2)边界值分析
通过分析,考虑如何确立边界情况。
(3)错误推测法
靠经验和直觉来推测程序中可能存在的各种错误,从而有针对性地编写用例。可以列举出可能的错误和可能发生错误的地方,然后选择用例。
(4)因果图
通过画因果图,在图上标明约束和限制,转换成判定表,然后设计测试用例。这适合于检查程序输入条件的各种组合情况。
(5)功能图
通过形式化表示程序的功能说明,机械地生成功能图的测试用例。
白盒测试用例设计包括:
(1)逻辑覆盖
以程序内在逻辑结构为基础的测试,包括以下几种类型。
①语句覆盖:每一条可执行语句至少覆盖一次。
②判定覆盖(分支覆盖):设计若干个测试用例,运行所测程序,使程序中每个判断的取真分支和取假分支至少执行一次。
③条件覆盖:设计足够多的测试用例,运行所测程序,使程序中每个判断的每个条件的每个可能取值至少执行一次。
④判定—条件覆盖:设计足够多的测试用例,运行所测程序,使程序中每个判断的每个条件的所有可能取值至少执行一次,并且每个可能的判断结果也至少执行一次。
⑤条件组合测试:设计足够多的测试用例,运行所测程序,使程序中每个判断的所有可能条件取值至少执行一次。
⑥路径测试:设计足够多的测试用例,运行所测程序,要覆盖程序中所有可能的路径。
(2)基本路径测试
在程序控制流图的基础上,通过分析控制构造的环路复杂性,导出基本可执行的路径集合,从而设计测试用例。包括以下5个方面。
①程序的控制流图:描述程序控制流的一种图示方法。