1、第12章 软件测试 第12章 软件测试 12.1 软件测试概述软件测试概述12.2 软件测试过程软件测试过程12.3 测试技术测试技术12.4 测试用例设计测试用例设计12.5 测试计划测试计划12.6 面向对象软件测试面向对象软件测试12.7 小结小结第12章 软件测试 12.1 软件测试概述软件测试概述12.1.1 软件测试的定义软件测试的定义软件测试的目的与软件工程所有其他阶段的目的都相反。软件工程的其他阶段都是“建设性”的:软件工程师力图通过对软件需求的理解,逐步设计出具体的软件系统,直到用一种适当的程序设计语言写出可以执行的程序代码。但是,软件测试的目的却是“破坏性”的,测试人员努力
2、设计出一系列测试方案,竭力证明已经建造好的软件系统程序中有错误,且不能按照预定要求正确工作。测试是最有效的排除和防止软件缺陷与故障的手段,并由此促进了软件测试理论与技术实践的快速发展。新的测试理论、测试方法、测试技术手段在不断涌出,软件测试机构第12章 软件测试 和组织也在迅速产生和发展,由此,软件测试技术职业也同步完善和健全起来。软件测试的研究可追溯到20世纪60年代,至今已有40多年的发展历史。但对于什么是软件测试(Soft Testing),还一直未能达成共识。目前软件测试的定义有多种:在1979年出版的一本经典著作软件测试艺术中,Glemford J.Myers曾对软件测试做过如下定义
3、:软件测试就是为了发现错误而执行程序或系统的过程。Paul C.Jorgensen认为:“测试显然要处理错误、缺陷、失效和事故。测试是采用测试用例来执行软件的活动。测试有两个显著的目标:找出失效,或演示正确的执行。”第12章 软件测试 1983年,IEEE提出了软件工程术语,软件测试定义为:“使用人工或自动手段来运行或测试某个系统的过程,其目的在于检验它是否满足规定的需求或是弄清预期结果与实际结果之间的差别。”这个定义相对来说比较完善,它明确提出了软件测试的最终目标是检验预期结果(用户需求)和实际结果之间的差别。当然它也有不完善的地方,比如“运行或测试某个系统”,因为软件测试并不一定要运行系统
4、,测试的定义中也不应该再出现“测试”的字眼。第12章 软件测试 12.1.2 软件测试的基本策略软件测试的基本策略软件测试是指在一定的软件测试标准、测试规范的指导下,依据测试项目的特定环境约束而规定的软件测试的原则、方式、方法的集合。任何一个完全测试或穷举测试的工作量都是巨大的,在实践中是行不通的,因此任何实际测试都不能保证被测程序中不遗漏错误或缺陷。为了最大程度地减少这种遗漏,同时最大限度地发现可能存在的错误,在实施测试前必须确定合适的测试方法和测试策略,并以此为依据制定详细的测试案例。第12章 软件测试 是不是所有软件测试都要运用现有软件测试方法去测试呢?答案是否定的。依据软件本身性质、规
5、模和应用场合的不同,我们将选择不同的测试方案,以最少的软/硬件、人力资源投入得到最佳的测试效果,这就是测试策略的目标所在。软件测试策略随着软件生命周期的变化以及软件测试方法、技术与工具的不同而发生着变化,这就要求我们在制定测试策略时应该综合考虑测试策略的影响因素及其依赖关系。这些影响因素可能包括测试项目资源因素、项目的约束和测试项目的特殊需要等。第12章 软件测试 1软件测试策略制定的步骤软件测试策略制定的步骤软件测试策略的制定可按以下步骤执行:1)输入(1)需要的软硬件资源的详细说明;(2)针对测试和进度约束而需要的人力资源的角色和职责;(3)测试方法、测试标准和完成标准;(4)目标系统的功
6、能性和技术性需求;(5)系统局限(即系统不能够提供的需求)等。2)输出输出已批准和签署的测试策略文档、测试用例、测试计划,需要解决方案的测试项目。第12章 软件测试 3)过程(1)确定测试的需求。测试需求所确定的是测试内容,即测试的具体对象。在分析测试需求时,可应用以下一般规则:测试需求必须是可观测、可测评的行为。如果不能观测或测评测试需求,就无法对其进行评估,以确定需求是否已经满足。在每个用例或系统的补充需求与测试需求之间不存在一对一的关系。用例通常具有多个测试需求;有些补充需求将派生一个或多个测试需求,而其他补充需求(如市场需求或包装需求)将不派生任何测试需求。第12章 软件测试 测试需求
7、可能有许多来源,其中包括用例模型、补充需求、设计需求、业务用例、与最终用户的访谈和软件构架文档等。应该对所有这些来源进行检查,以收集可用于确定测试需求的信息。(2)评估风险并确定测试优先级。成功的测试需要在测试工作中成功地权衡资源约束和风险等因素。为此,应该确定测试工作的优先级,以便先测试最重要、最有意义或风险最高的用例或构件。为了确定测试工作的优先级,需执行风险评估和实施概要,并将其作为确定测试优先级的基础。(3)确定测试策略。一个好的测试策略应该包括实施的测试类型和测试的目标、实施测试的阶段、技术、用于评估的测试结果和测试是否完成的评测和标准、对测试策略所述的测试工作存在影响的特殊事项等内
8、容。第12章 软件测试 如何才能确定一个好的测试策略呢?我们可以从基于测试技术的测试策略、基于测试方案的测试策略两个方面来回答这个问题。基于测试技术的测试策略的要点。著名测试专家给出了使用各种测试方法的综合策略;任何情况下都必须使用边界值测试方法;必要时使用等价类划分方法补充一定数量的测试用例;对照程序逻辑,检查已设计出的测试用例的逻辑覆盖程度,看是否达到了要求;如果程序功能规格说明中含有输入条的组合情况,则可以选择因果图方法。第12章 软件测试 基于测试方案的测试策略。对于基于测试方法的测试策略,一般来说应该考虑如下方面:根据程序的重要性和一旦发生故障将造成的损失来确定它的测试等级和测试重点
9、;认真研究,使用尽可能少的测试用例发现尽可能多的程序错误,避免测试过度和测试不足。第12章 软件测试 2软件测试涉及的关键问题软件测试涉及的关键问题软件测试涉及的关键问题包括以下四个方面:(1)测试由谁来执行(Who)。测试通常由软件产品开发设计的作者和测试者两种角色来执行。开发者通过开发形成产品,包括源代码以及相关的设计文档等;测试者通过测试来检测产品中是否存在缺陷,包括根据特定测试目的而设计的测试用例、构造测试、执行测试和评估测试等。此外,在验收测试过程中,还应邀请实际用户或用户代表来参与测试。第12章 软件测试(2)测试什么(What)。在实际测试过程中,表现在程序中的故障通常并不一定是
10、因为编码错误而产生的,它可能是因为详细设计、概要设计阶段,甚至是需求分析阶段的问题所致。即使对源程序进行测试,所发现故障的根源也可能是在开发前期的某个阶段。要排除故障、修正错误也必须追溯到前期的工作。事实上,软件需求分析、设计和实施阶段是软件故障的主要来源。第12章 软件测试(3)什么时候进行测试(When)。测试过程并不是和开发过程完全独立的,它可以与开发过程并行进行,也可以是在开发完成某个阶段任务之后的活动或者是开发结束后的活动,即模块开发结束之后可以进行测试,也可以推迟到各模块装配成为一个完整的程序之后再进行测试。一般开发经验证明,随着开发的不断深入,若有模块没有进行及时的测试,则该模块
11、隐藏的缺陷对整个软件的潜在破坏作用就更加巨大。第12章 软件测试(4)怎样进行测试(How)。软件“规范”说明了软件本身应该达到的目标,程序“实现”则是一种对应各种输入如何产生输出结果的算法。换言之,规范界定了一个软件要做什么,而程序实现则规定了软件应该怎样做。对软件进行测试就是根据软件的功能规范说明和程序实现,利用各种测试方法,生成有效的测试用例,对软件进行测试。对一个系统作的测试越多,就越能确保它的正确性。然而,软件测试通常不能保证系统的运行百分之百的正确。因此,软件测试在确保软件质量方面的主要贡献在于它能发现那些在一开始就应避免的错误。第12章 软件测试 12.1.3 软件测试的基本原则
12、软件测试的基本原则1“零缺陷零缺陷”与与“足够好足够好”原则原则“零缺陷”指的是软件没有任何缺陷,“足够好”指的是只要软件达到一定的质量要求,就可以停止测试了。一般来说,对相对复杂的系统来说要实现零缺陷是不可能的,只能想办法把软件缺陷数控制在可忍受的范围内。而“足够好”原则正是通过确定投入与产出比的最佳点来制定最低测试通过标准和测试内容的。比如,通过测试的标准可以为:遗留缺陷数在10个以下,其中严重缺陷在5个以下;测试用例执行率达100%,通过率为95%,或者单元测试中语句覆盖率达100%,分支覆盖达85%。一般测试通过标准没有统一的规定,可按具体情况具体对待。第12章 软件测试 2“非穷举测
13、试非穷举测试”原则原则此原则意即不要试图穷举测试。穷举测试指的是测试考虑所有可能的测试用例。但是,实际上,即使是很小规模的系统,穷举测试用例也会是非常巨大的。因此,要在测试用例的设计上仔细考虑,力求设计出优秀的测试用例,用最少的测试用例达到最大的覆盖率。第12章 软件测试 3“第三方测试第三方测试”原则原则此原则意即避免开发人员测试自己的程序。测试应该由独立的第三方来完成。开发者对自己的程序印象深刻,并总是敝帚自珍,认为自己的智慧和努力得到的成果是可信的。但是如果在设计时就产生理解错误,或因不良编程习惯留下隐患,那他本人就很难发现这类错误。开发者对程序的功能、接口十分熟悉,因此很难模仿大众用户
14、产生使用不当而引发的错误。另外,测试是一种“破坏性”的活动,力求发现系统的错误,而对自己的成果,开发者往往不自觉地会避免错误的发生。因此,只有把测试交给其他人来执行,才能保证测试活动的完备性和公正性。第12章 软件测试 4“尽早测试尽早测试”原则原则此原则意即测试要尽早执行。软件生命周期包括需求分析、设计、编码、测试、验收和维护等阶段,在每个阶段都会产生缺陷。实践证明,大多数情况下,需求分析阶段引入的缺陷是最多的,而修复成本却是最低的。因此软件测试应该尽早执行,越早执行,风险越小,所花费的成本就越低,缺陷产生的危害也就越小。第12章 软件测试 5“缺陷的二八缺陷的二八”原则原则很多初学软件工程
15、的人会认为,在某一段代码中发现的缺陷越多,则该代码段中遗留的缺陷就会越少,从而推断潜在的缺陷也随之减少。但这种观点是错误的,一般情况下,软件80%的缺陷集中在20%的模块中。我们测试的时候要抓住主要矛盾,如果发现某一程序模块比其他的模块有更多的缺陷,就要投入主要的人力和精力重点测试这20%的模块,以提高我们的测试效率。通常,我们也会把缺陷的“二八原则”称为缺陷的群集现象或者是虫子窝现象。第12章 软件测试 6“严格计划性严格计划性”原则原则此原则意即严格执行测试计划,排除测试的随意性。在测试执行前应该制定详细的测试计划,测试计划是对测试的范围、方式、资源以及测试所需要的时间做出一个预先的指定方
16、针。而测试的内容必须包括进行测试的项目、产品功能的测试、所需要进行的测试工作、每位测试人员所应该负责的测试工作,以及与测试有关的风险。测试计划应该清晰明确,无二义性,而测试的过程应该严格按照该计划执行,这样才能保证测试的有效性。第12章 软件测试 7“测试结果全面检查测试结果全面检查”原则原则此原则意即对每一个测试结果进行全面检查。虽然软件测试只能证明已发现的软件错误,无法报告潜在的软件错误,也不能保证软件错误全部找到,但是对每一个测试结果做全面检查却是必要的,因为有些错误的征兆在输出实测结果时已经明显地出现了,但是如果不仔细全面地检查测试结果,就会使这些错误被遗漏掉。第12章 软件测试 8“
17、妥善保存文档妥善保存文档”原则原则此原则意即妥善保存一切测试过程文档,为维护工作提供充分的资料。测试过程的文档包括测试计划、测试用例、出错统计和最终分析报告,如同软件开发过程的所有文档和报告一样,测试文档也应该进行归档保存,测试的重现往往要靠这些文档。第12章 软件测试 12.1.4 软件测试与软件开发各阶段的关系软件测试与软件开发各阶段的关系软件开发从获取需求、分析设计到编码实现,是一个自顶向下、逐步精化的过程。而软件测试过程却是自底向上,从局部到整体,逐步集成的过程。在开发的不同阶段,会出现不同类型的缺陷和错误,需要不同的测试技术和方法来发现这些缺陷。在软件测试方面,V模型是最广为人知的模
18、型,尽管在实际应用中,犹如瀑布模型一般,它存在着许多弊端,但是V模型非常明确地划分了软件测试过程的不同级别,并阐述了软件测试阶段和开发过程各阶段的对应关系。第12章 软件测试 如图12.1所示,左边从上至下的是开发过程各阶段,与其相对应的是右边自下而上的部分,即测试的各个阶段。开发阶段的一侧,从需求分析开始,而后将这些需求不断地转换到系统的概要设计和详细设计中去,最后编码实现,完成软件系统。在测试执行的一侧,先从单元测试开始,然后是集成测试、系统测试和验收测试。低一级的测试是高一级测试的准备和条件。第12章 软件测试 图12.1 软件测试V模型 第12章 软件测试 12.1.5 测试文档测试文
19、档1测试文档的主要内容测试文档的主要内容测试文档包括以下主要内容。1)测试计划(Test Plan)测试计划是测试工作的指导性文档,规定了测试活动的范围、方法、资源和进度;明确了正在测试的项目、要测试的特性、要执行的测试任务、每个任务的负责人以及与计划相关的风险。主要内容:测试目标、测试方法、测试范围、测试资源、测试环境和工具、测试体系结构、测试进度表。第12章 软件测试 2)测试规范(Test Specification)测试规范从整体上规定测试案例的运行环境、测试方法、生成步骤、执行步骤以及调试和验证的步骤。主要内容:系统运行环境、总体测试方法、测试用例的生成步骤、测试用例的执行步骤、调试
20、和验证。3)测试用例(Test Case)测试用例是数据输入和期望结果组成的对,其中“输入”是对被测软件接收外界数据的描述,“期望结果”是对相应输入软件应该出现的输出结果的描述。测试用例还应明确指出使用具体测试案例产生的测试程序的任何限制。第12章 软件测试 测试用例可以被组织成一个测试系列,即为实现某个特定的测试目的而设计的一组测试用例。例如,一部分测试用例用来测试系统的兼容性,另一部分用来测试系统在特定的环境中,其典型应用是否能够很好地运作。4)缺陷报告(Bug Report)缺陷报告记录在需要调查研究的测试过程期间发生的任何事件。简而言之,就是记录软件缺陷。主要内容:缺陷编号、题目、状态
21、、提出、解决、所属项目、测试环境、缺陷报告步骤、期待结果、附件。在报告缺陷时,一般要讲明缺陷的严重性和优先级。严重性表示软件的恶劣程度,反映其对产品和用户的影响。优先级表示修复缺陷的重要程度和应该何时修复。第12章 软件测试 2测试文档的分类测试文档的分类根据测试文档所起的作用不同,通常把测试文档分成两类,即测试计划和测试分析报告。测试计划详细规定测试的要求,包括测试的目的和内容、方法和步骤,以及测试的准则等。由于要测试的内容可能涉及软件需求和软件设计,因此必须及早开始测试计划的编写工作。不应在着手测试时才开始考虑测试计划。通常,测试计划的编写从需求分析阶段开始,到软件设计阶段结束时完成。测试
22、分析报告用来对测试结果进行分析说明,经过测试后,证实了软件具有的能力,以及它的缺陷和限制,并给出评价的结论性意见,这些意见既是对软件质量的评价,又是决定该软件能否交付用户使用的依据。由于要反映测试工作的情况,自然要在测试阶段内编写。第12章 软件测试 3测试文档的重要性测试文档的重要性测试文档不只在测试阶段才考虑,应在软件开发的需求分析阶段就开始着手,因为测试文档与用户有着密切的关系。设计阶段的一些设计方案也应在测试文档中得到反映,以利于设计的检验。测试文档对于测试阶段工作的指导与评价作用更是非常明显的。需要特别指出的是,在已开发的软件投入运行的维护阶段,常常还要进行再测试或回归测试,这时仍需
23、用到测试文档。测试文档的重要性表现在以下几个方面:(1)验证需求的正确性。测试文档中规定了用以验证软件需求的测试条件,研究这些测试条件对弄清用户需求的意图是十分有益的。第12章 软件测试(2)检验测试资源。测试计划不仅要用文档的形式把测试过程规定下来,还应说明测试工作必不可少的资源,进而检验这些资源是否可以得到,即它的可用性如何。如果某个测试计划已经编写出来,但所需资源仍未落实,那就必须及早解决。(3)明确任务的风险。有了测试计划,就可以弄清楚测试可以做什么,不能做什么。了解测试任务的风险有助于对潜伏的可能出现的问题事先作好思想上和物质上的准备。(4)生成测试用例。测试用例的好坏决定着测试工作
24、的效率,选择合适的测试用例是作好测试工作的关键。在测试文档编制过程中,按规定的要求精心设计测试用例有重要的意义。第12章 软件测试(5)评价测试结果。测试文档包括测试用例,即若干测试数据及对应的预期测试结果。完成测试后,将测试结果与预期的结果进行比较,便可对已进行的测试提出评价意见。(6)再测试。测试文档规定和说明的内容对维护阶段由于各种原因进行的再测试是非常有用的。(7)决定测试的有效性。完成测试后,把测试结果写入文档,这对分析测试的有效性,甚至整个软件的可用性提供了依据,同时还可以证实有关方面的结论。第12章 软件测试 12.2 软件测试过程软件测试过程软件产品在交付使用之前,一般需要经过
25、单元测试、集成测试、系统测试和验收测试,具体步骤如图12.2所示。图12.2 软件测试步骤第12章 软件测试 12.2.1 单元测试单元测试1代码审查代码审查人工测试源程序可以由编写者本人非正式地进行,也可以由审查小组正式进行。后者称为代码审查,它是一种非常有效的程序验证技术,对于典型的程序来说,可以查出30%70%的逻辑设计错误和编码错误。审查小组最好由下述四人组成:组长,他应该是一个很有能力的程序员,而且没有直接参与这项工程;程序的设计者;程序的编写者;程序的测试者。第12章 软件测试 如果一个人既是程序的设计者又是编写者,或既是编写者又是测试者,则审查小组中应该再增加一个程序员。审查之前
26、,小组成员应该先研究设计说明书,力求理解这个设计。为了帮助理解,可以先由设计者扼要地介绍他的设计,再由程序的编写者解释他是怎样用程序代码实现这个设计的,通常是逐个语句地讲述程序的逻辑,小组其他成员仔细倾听他的讲解,并力图发现其中的错误。当发现错误时由组长记录下来,审查会继续进行(审查小组的任务是发现错误而不是改正错误)。审查会还有另外一种常见的进行方法(称为预排):由一个人扮演“测试者”,其他人扮演“计算机”。会前测试者准备好测试方案,会上由扮演计算机的成员模拟计算机执行被测第12章 软件测试 试的程序。当然,由于人执行程序速度极慢,因此测试数据必须简单,测试方案的数目也不能过多。但是,测试方
27、案本身并不十分关键,它只起一种促进思考、引起讨论的作用。在大多数情况下,通过向程序员提出关于他的程序的逻辑和他编写程序时所做的假设的疑问,可以发现比由测试方案直接发现的错误还多的错误。代码审查比计算机测试优越的是:一次审查会上可以发现许多错误;用计算机测试的方法发现错误之后,通常需要先改正这个错误才能继续测试,因此错误是一个一个地被发现并被改正的。也就是说,采用代码审查的方法可以减少系统验证的总工作量。第12章 软件测试 实践表明,对于查找某些类型的错误来说,人工测试比计算机测试更有效;对于其他类型的错误来说则刚好相反。因此,人工测试和计算机测试是互相补充、相辅相成的,缺少其中任何一种方法都会
28、使查找错误的效率降低。2测试软件测试软件模块并不是一个独立的程序,因此必须为每个单元测试开发驱动模块和(或)桩模块。通常驱动模块也就是一个“主程序”,它接收测试数据,把这些数据传送给被测试的模块,并且打印出有关的结果。桩模块代替被测试的模块所调用的模块。因此桩模块也可以称为“虚拟子程序”,它使用被它代替的模块的接口,可能做最少量的数据操作,打印出对入口的检验或操作结果,并且把控制归还给调用它的模块。第12章 软件测试 例如,图12.3是一个正文加工系统的部分层次图,假定要测试其中编号为3.0的关键模块正文编辑模块。因为正文编辑模块不是一个独立的程序,所以需要有一个测试驱动模块来调用它。这个驱动
29、模块说明必要的变量,接收测试数据字符串,并且设置正文编辑模块的编辑功能。因为在原来的软件结构中,正文编辑模块通过调用它的下层模块来完成具体的编辑功能,所以需要有桩模块简单地模拟这些下层模块。为了简单起见,测试时可以设置的编辑功能只有修改(CHANGE)和添加(APPENID)两种,用控制变量CFUNCT标记要求的编辑功能,而且只用一个桩模块模拟正文编辑模块的所有下层模块。下面是用伪码书写的桩模块和驱动模块。第12章 软件测试 图12.3 正文加工系统的层次图第12章 软件测试.TEST STUB(*测试正文编辑模块用的存根程序*)初始化;输出信息“进入了正文编辑程序”;输出“输入的控制信息是”
30、CFUNCT;输出缓冲区中的字符串;IF CFUNCT=CHANGE THEN 把缓冲区中第二个字改为*ELSE 在缓冲区的尾部加?END IF:输出缓冲区中的新字符串;END TEST STUB 第12章 软件测试.TEST DRIVER(*测试正文编辑模块用的驱动程序*)说明长度为 2500 个字符的一个缓冲区;把 CFUNCT 置为希望测试的状态;输入字符串;调用正文编辑模块;停止或再次启动;END TEST DRIVER 第12章 软件测试 驱动模块和桩模块代表开销,也就是说,为了进行单元测试必须编写测试软件,但是通常并不把它们作为软件产品的一部分交给用户。许多模块不能用简单的测试软件
31、充分测试,为了减少开销,可以使用将要介绍的渐增式测试方法,在集成测试的过程中同时完成对模块的详尽测试。模块的内聚程度高,可以简化单元测试过程。如果每个模块只完成一种功能,则需要的测试方案数目将明显减少,模块中的错误也更容易预测和发现。第12章 软件测试 12.2.2 集成测试集成测试集成测试是测试和组装软件的系统化技术,它把模块按照设计要求组装起来同时进行测试,主要目标是发现与接口有关的问题。例如,数据穿过接口时可能丢失;一个模块对另一个模块可能由于疏忽而造成有害影响;把子功能组合起来可能不产生预期的主功能;个别看来是可以接受的误差可能积累到不能接受的程度;全程数据结构可能有问题,等等。事实上
32、,可能发生的接口问题多得不胜枚举。第12章 软件测试 由模块组装成程序时有两种方法。一种方法是先分别测试每个模块,再把所有模块按设计要求放在一起结合成所要的程序,这种方法称为非渐增式测试方法;另一种方法是把下一个要测试的模块同已经测试好的那些模块结合起来进行测试,测试完以后再把下一个应该测试的模块结合进来测试,这种每次增加一个模块的方法称为渐增式测试。非渐增式测试一下子把所有模块放在一起,并把整个程序作为一个整体来进行测试,测试者面对的场面往往混乱不堪;测试时会遇到许许多多的错误,改正错误更是极端困难,因为在庞大的程序中想要诊断定位一个错误是非常复杂、困难的。而且一旦改正一个错误之后,马上又会
33、遇到新的错误,这个过程会继续下去,看起来好像永远也没有尽头。第12章 软件测试 渐增式测试与“一步到位”的非渐增式测试相反,它把程序划分成小段来构造和测试,在这个过程中比较容易分离和改正错误,对接口可能进行更彻底的测试,而且可以使用系统化的测试方法。因此,在进行集成测试时普遍使用渐增式测试方法。下面讨论两种不同的渐增式集成策略自顶向下集成和自底向上集成。第12章 软件测试 1自顶向下集成自顶向下集成自顶向下的集成(结合)方法是一个日益为人们广泛采用的组装软件的途径,它从主控制模块(主程序)开始,沿着软件的控制层次向下移动,从而逐渐把各个模块结合起来。在把附属于(以及最终附属于)主控制模块的那些
34、模块组装到软件结构中去时,或者使用深度优先的策略,或者使用宽度优先的策略,如图12.4所示。第12章 软件测试 图12.4 自顶向下集成第12章 软件测试 从图12.4可以看出,深度优先的结合方法先组装在软件结构的一条主控制通路上的所有模块。选择一条主控制通路取决于应用的特点,并且有很大的任意性。例如,选取左通路,首先结合模块M1、M2和M5,然后M8或M6(如果为了使M2具有适当功能需要M6的话)将被结合进来,之后构造中央的和右侧的控制通路。而宽度优先的结合方法,是沿软件结构水平地移动,把处于同一个控制层次上的所有模块组装起来。对于图12.4来说,首先结合模块M2、M3和M4(代替桩模块S4
35、),然后结合下一个控制层次中的模块M5、M6和M7。如此继续进行下去,直到所有模块都被结合进来为止。第12章 软件测试 把模块结合进软件结构的具体过程由下述四个步骤完成:(1)对主控制模块进行测试,测试时用存根程序代替所有直接附属于主控制模块的模块;(2)根据选定的结合策略(深度优先或宽度优先),每次用一个实际模块代换一个存根程序(新结合进来的模块往往又需要新的存根程序);(3)在结合进一个模块的同时进行测试;(4)为了保证加入模块没有引进新的错误,可能需要进行回归测试(即全部或部分地重复以前做过的测试)。第12章 软件测试 从步骤(2)开始不断地重复进行上述过程,直到构造起完整的软件结构为止
36、。图12.4描绘了这个过程。假设选取深度优先的结合策略,软件结构已经部分地构造起来了,下一步桩模块S7将被模块M7取代。M7可能本身又需要存根程序,以后这些存根程序也将被相应的模块所取代。自顶向下的结合策略能够在测试的早期对主要的控制或关键的抉择进行检验。在一个分解得好的软件结构中,关键的抉择位于层次系统的较上层,因此首先碰到。如果主要控制确实有问题,则早期认识到这类问题是很有好处的,可以及早想办法解决。如果选择深度优先的结合方法,则可以在早期实现软件的一个完整的功能并且验证这个功能。早期证实软件的一个完整的功能可以增强开发人员和用户双方的信心。第12章 软件测试 自顶向下的方法讲起来比较简单
37、,但是实际使用时可能会遇到逻辑上的问题。这类问题中最常见的是,为了充分地测试软件系统的较高层次,需要用到在较低层次上的处理。然而在自顶向下测试的初期,存根程序代替了低层次的模块,因此,在软件结构中没有重要的数据自下往上流。为了解决这个问题,测试人员有两种选择:(1)把许多测试推迟到用真实模块代替了存根程序以后再进行;(2)从层次系统的底部向上组装软件。方法(1)失去了在特定的测试和组装特定的模块之间的精确对应关系,这可能导致在确定错误的位置和原因时发生困难。后一种方法称为自底向上的测试,下面讨论这种方法。第12章 软件测试 2自底向上集成自底向上集成自底向上测试从“原子”模块(即在软件结构最低
38、层的模块)开始组装和测试。因为是从底部向上结合模块,总能得到需要的下层模块处理功能,所以不需要存根程序。用下述步骤可以实现自底向上的结合策略:(1)把低层模块组合成实现某个特定的软件子功能的簇;(2)写一个驱动模块(用于测试的控制程序),协调测试数据的输入和输出;(3)对由模块组成的子功能簇进行测试;(4)去掉驱动模块,沿软件结构自下向上移动,把子功能簇组合起来形成更大的子功能簇。第12章 软件测试 上述(2)(4)步实质上构成了一个循环。图12.5描绘了自底向上的集成过程。首先把模块组合成簇1、簇2和簇3,使用驱动程序(图中用虚线框表示)对每个子功能簇进行测试。簇1和簇2中的模块附属于模块M
39、a,去掉驱动程序D1和D2,把这两个簇直接同Ma连接起来。类似地,在和模块Mb结合之前去掉簇3的驱动程序D3。最终Ma和Mb这两个模块都与模块Mc结合起来。随着结合向上移动,对测试驱动程序的需要也减少了。事实上,如果软件结构的顶部两层用自顶向下的方法组装,则可以明显减少驱动程序的数目,而且也将大大简化簇的结合。第12章 软件测试 图12.5 自底向上集成第12章 软件测试 3回归测试回归测试每当一个新模块作为集成测试的一部分加进来时,软件就发生了变化:建立了新的数据流路径;可能出现新的I/O操作;激活了新的控制逻辑。这些变化可能使原来工作正常的功能出现问题。在集成测试的范畴中,所谓回归测试,是
40、指重新执行已经做过的测试的某个子集,以保证上述这些变化没有带来非预期的副作用。更广义地说,任何成功的测试都会发现错误,而且错误必须被改正。每当改正软件错误时,软件配置的某些成分(程序、文档或数据)也被修改了。回归测试就是用于保证由于测试或其他原因引起的变化,不会导致非预期的行为或额外错误的活动。第12章 软件测试 回归测试可以通过重新执行所有测试用例的一个子集来人工地进行,也可以使用自动化的捕获回放工具自动进行。利用捕获回放工具,软件工程师能够捕获测试用例和实际运行结果,然后可以回放(即重新执行测试用例)并比较所得到的运行结果。回归测试集(已执行过的测试用例的子集)包括下述三种不同的测试用例。
41、(1)检测软件全部功能的代表性测试用例。(2)专门针对可能受修改影响的软件功能的附加测试。(3)针对被修改过的软件成分的测试。第12章 软件测试 在进行集成测试的过程中,回归测试的数量可能变得非常大。因此,应该把回归测试集设计为只包括这样一些测试,即测试检测程序每个主要功能中的一类或多类错误。一旦修改了软件之后就重新执行检测程序中每个功能的全部测试用例,这种设计是低效而且不切实际的。第12章 软件测试 4不同集成测试策略的比较不同集成测试策略的比较上面介绍了集成测试的两种策略。到底哪种方法更好一些呢?一般来说,一种方法的优点正好对应于另一种方法的缺点。自顶向下测试方法的主要优点是不需要测试驱动
42、程序,能够在测试阶段的早期实现并验证系统的主要功能,而且能在早期发现上层模块的接口错误。自顶向下测试方法的主要缺点是需要存根程序,可能遇到与此相联系的测试困难,低层关键模块中的错误发现得较晚,而且用这种方法在早期不能充分展开人力。可以看出,自底向上测试方法的优缺点与上述自顶向下测试方法的优缺点刚好相反。第12章 软件测试 在测试实际的软件系统时,应该根据软件的特点以及工程进度安排,选用适当的测试策略。一般来说,纯粹自顶向下或纯粹自底向上的策略可能都不实用,人们在实践中创造出了许多混合策略。(1)改进的自顶向下测试方法。基本上使用自顶向下的测试方法,但是在早期,就使用自底向上的方法测试软件中的少
43、数关键模块。一般的自顶向下方法所具有的优点在这种方法中都有,而且能在测试的早期发现关键模块中的错误;但是,它的缺点也比自顶向下方法多一条,即测试关键模块时需要驱动程序。第12章 软件测试(2)混合法。对软件结构中的较上层使用的是自顶向下方法,对软件结构中的较下层使用的是自底向上方法,两者相结合。这种方法兼有两种方法的优点和缺点,当被测试的软件中关键模块比较多时,这种混合法可能是最好的折中方法。在进行集成测试时,测试人员应该能够识别出关键模块。关键模块具有下述的一个或多个特征:与多项软件需求有关;含有高层控制(模块位于程序结构的较高层次);本身是复杂的或容易出错的(可以用环形复杂度来指示);有确
44、定的性能需求。应该尽可能早地测试关键模块。此外,回归测试也应该着重测试关键模块的功能。第12章 软件测试 12.2.3 系统测试系统测试1系统测试的内容系统测试的内容系统测试是把经过测试的子系统配装成一个完整的系统来测试。在这个过程中不仅应该发现设计和编码的错误,还应该验证系统确实提供了需求说明书中指定的功能,而且系统的动态性也符合预定要求。在这个测试步骤中发现的往往是软件设计中的错误,也可能发现需求说明中的错误。系统测试(System Test)就是要求对软件系统进行全面的测试,最终确保软件系统是否满足产品需求并且遵循系统设计。在系统测试的过程中,将验证系统的功能、结构的稳定性以及非功能测试
45、需求,如可靠性、性能等。第12章 软件测试 系统测试主要应用黑盒测试技术测试系统的高级需求,因为黑盒测试的要求是:如果已经知道了产品应该具有的功能,可以通过测试来检验是否每个功能都能正常使用。在系统测试中,已经知道了系统的功能,只是用来验证是否满足要求,所以用黑盒测试。系统测试流程如图12.6所示。如果在系统测试过程中发现一些缺陷,那么就必须用统一的缺陷管理工具来管理,这时就要求开发人员应当及时消除这些缺陷(改错)。系统测试不仅需要测试产品系统的软件,还要测试软件所依赖的硬件、外设甚至还包括某些数据、某些支持软件及其接口等。因此,必须将各种依赖的资源与系统中的软件相互结合起来,在系统运行的实际
46、环境中来对整个系统进行测试。第12章 软件测试 系统测试主要应用黑盒测试技术测试系统的高级需求,因为黑盒测试的要求是:如果已经知道了产品应该具有的功能,可以通过测试来检验是否每个功能都能正常使用。在系统测试中,已经知道了系统的功能,只是用来验证是否满足要求,所以用黑盒测试。系统测试流程如图12.6所示。如果在系统测试过程中发现一些缺陷,那么就必须用统一的缺陷管理工具来管理,这时就要求开发人员应当及时消除这些缺陷(改错)。系统测试不仅需要测试产品系统的软件,还要测试软件所依赖的硬件、外设甚至还包括某些数据、某些支持软件及其接口等。因此,必须将各种依赖的资源与系统中的软件相互结合起来,在系统运行的
47、实际环境中来对整个系统进行测试。第12章 软件测试 图12.6 系统测试流程第12章 软件测试 在系统测试过程中,项目经理要组建系统测试小组。系统测试小组应当根据项目所要完成的功能确定测试内容。一般地,系统测试的主要内容包括:(1)功能测试。功能测试的目的就是测试软件系统的功能是否满足用户的需求,测试依据是需求文档,如产品需求规格说明书等。由于正确性是软件最重要的质量因素之一,所以功能测试必不可少。(2)健壮性测试。健壮性测试的目的是测试软件系统在发生异常情况时是否仍然能正常运行。健壮性有两层含义:一是容错能力,二是恢复能力。第12章 软件测试(3)性能测试。性能测试的目的是测试软件系统处理事
48、务的速度,一是为了得到某些性能数据供人们参考(例如用于宣传);二是为了检验性能是否符合需求。针对整个系统的测试,主要包括并发性能测试、负载测试、压力测试、强度测试、破坏性测试。并发性能测试主要用来评估系统交易或业务在渐增式并发情况下处理瓶颈及能够接收业务的性能过程;强度测试是在有限的资源情况下,找出因资源不足或资源竞争使用而导致的错误;破坏性测试重点关注超出系统正常负荷N倍情况下,错误出现状态和出现比率以及错误的恢复能力。第12章 软件测试(4)用户界面测试。用户界面测试的目的是在确保用户界面能够通过测试对象控件或入口得到相应访问的情况下,测试用户界面的风格是否满足用户的要求,例如界面是否美观
49、、直观,人机交互是否友好,易操作性是否较好等。(5)安全性(security)测试。安全性测试的安全性主要包括了两部分:数据的安全性和操作的安全性。安全性测试核实只有规定的数据才可以访问系统,其他不符合规定的数据不能够访问系统;核实只有规定的操作权限才可以访问系统,其他不符合规定的操作权限不能够访问系统。(6)安装与反安装测试。第12章 软件测试 2系统测试步骤系统测试步骤1)制定系统测试计划 系统测试小组各成员共同讨论测试计划,其中,测试组长按照指定的模板起草系统测试计划。该计划主要包括:(1)测试方法。(2)测试环境与辅助工具。(3)测试范围(内容)。(4)测试完成准则。(5)人员与任务表
50、。最后项目经理审批系统测试计划。该计划得到批准后,接着开始设计系统测试用例。第12章 软件测试 2)设计系统测试用例 系统测试小组各成员依据系统测试计划和指定的模板,设计系统测试用例,并且测试组长邀请开发人员和同行专家,对系统测试用例进行技术评审。该测试用例通过技术评审后,接着就可以执行系统测试。3)执行系统测试 系统测试小组各成员依据系统测试计划和系统测试用例,执行系统测试,并将测试结果记录在系统测试报告中。在该过程中用“缺陷管理工具”来管理所发现的缺陷,并及时报告给开发人员。第12章 软件测试 4)缺陷管理与改错 在步骤1)至3)的过程中,任何人发现软件系统中的缺陷都必须使用指定的“缺陷管