您现在所在的位置是:首页 > 业界新闻

服装管理软件测试

1.1服装管理软件测试的基本概念
1.1.1软件的故障和失效
在软件开发的理想情况下.如果开发人员具有炉火纯青的技能,生产出来的每个程序在每次运行时都能够正确而适当地工作。但这种理想并不现实,设计和开发出来的软件系统往往会存在故障或失效,通常也称为软件没有做好需求描述的事情。
软件系统的失效可能是由下面的一些原因造成的:
(1)规约说明可能不正确,或者遗漏了某些需求,也就是需求规约说明可能没有准确地陈述客户想要的或需要的。
(2)对于指定的软硬件,需求规约说明中可能包含不可能实现的内容。
(3)系统设计中可能包含故障,例如,数据库和查询语言的设计不可能对用户进行授权。
(4)程序设计中可能包含故障,例如,构件描述中包含不能够正确处理这种情况的访问控制算法。
(5)程序代码出现错误或者不完整。
这些原因都会导致系统在某些方面出现一个或多个故障。
软件系统中的故障一般包括如下几种。
1)算法故障
算法故障是指由于处理步骤中的某些错误,使得对于给定的输入,相关的算法没有产生适当的输出。典型的算法故障包括:分支太早、分支太迟、忘记针对特定的条件进行测试、对错误的条件进行了测试、对不合适的数据类型变量进行比较、忘记了初始化变量或忘记了设置循环不变量等。
2)计算故障和精度故障
计算故障是指一个公式的实现是错误的;而精度故障是指计算结果没有达到要求的精度。
3)文档故障
文档故障是指文档与程序实际所做的事情不一致。通常,文档从程序设计导出,应该对程序员想要程序做什么提供非常清晰的描述,但那些功能的实现是有问题的。由于多数人在对代码进行检查和修改时,都倾向于依赖文档,这样的故障可能导致在软件开发生命周期的后期产生大量的其他故障。
4)能力故障或边界故障
能力故障或边界故障是指所开发出来的系统活动到达指定的极限时,系统性能会变得不可接受。
5)吞吐量故障或性能故障
吞吐量故障或性能故障是指所开发出来的系统不能以需求规定的速度执行。
在所开发出来的系统中出现故障,就认为此软件系统出现了质量问题或者不可靠了。为此,就需要引入相应技术来提高软件的质量。

1.1.2软件测试的概念
为了保证所开发软件系统的质量和可靠性,人们常常在软件需求分析、设计、程序设计等各个阶段结束之前,对软件进行各种严格的技术评审工作。但即便如此,由于人类本身能力的局限性,评审也不能发现系统中的所有错误和缺陷。这些错误和缺陷(特别是在程序设计阶段引进的大量错误)在系统交付后投人生产性运行之前如果不能加以排除的话,在运行中迟早也会暴露出来的。到那时候,不仅改正这些错误需要花费高昂的代价,而且往往造成严重的后果。软件测试就是在软件投入生产性运行之前,对所开发出来的软件系统进行的一次最终复审,是软件质量控制的最关键步骤之一。
那么,什么是服装管理软件测试呢?
大多数测试专业人员都赞同GrenfordJ.Myers对测试的定义:“测试是为发现错误而执行程序的过程。”并且Myers还认为“好的测试方案是极可能发现迄今为止尚未发现的错误的测试方案”,“成功的测试是发现了至今为止尚未发现的错误的测试”。这就意味着软件测试的活动是一个具有破坏性的过程,定义也暗示了对于一个特定的软件,应该如何去设计测试用例,以及哪些人应该而哪些人又不应该执行测试。
根据这种观点,Myers认为测试是以查找错误为中心,而不是为了演示软件的正确功能。但是如果只从字面意思去理解,可能就会产生误导,认为发现错误是软件测试的唯一目的,实际上并非如此,这是因为:
(1)测试不仅仅是为了发现错误,通过分析错误产生的原因和发生趋势,可以帮助开发人员发现软件过程中的缺陷,并加以改进。
(2)对测试结果的分析能够帮助测试人员设计出更具有针对性的测试方法,改善测试的效率和有效性。
(3)没有发现错误的测试也是有价值的,它也是保证软件质量的一种方法。
因此,如果在测试中发现了可以纠正的缺陷,或者测试最终确定没有其他缺陷,都应将这次测试称作是“成功的”测试。而所谓“不成功的”测试,仅指未能适当地对程序进行检查.未能找出程序中潜藏缺陷的测试。
软件测试能够帮助识别所开发的系统的正确度、完全度和质量,是软件质量保证的重要子域。

1.1.3测试的内容和原则
软件测试就是利用测试工具按照测试方案对产品功能和性能测试,并对测试方案中可能出现的问题进行分析和评估。测试工作的主要内容是验证(Verification)和确认(Validation)。
验证是保证软件正确地实现了一些特定功能的一系列活动,即保证软件做了你所期望的事情;而确认是一系列的活动和过程,目的是想证实在一个给定的外部环境中软件的逻辑正确性,即保证软件以正确的方式来做这个事件。
软件测试的对象不仅仅是程序的测试,还应该包括整个软件开发期间各个阶段所产生的文档,如需求规约说明、各类设计文档等,而主要对象还是源程序。
为了保证测试的有效性和正确性,软件测试过程中应该满足以下的几大原则。
(1)开发人员和开发组织应当避免测试自己的程序。
由开发人员来测试自己的代码是一件很不妥当的事情。开发和测试生来就是不同的活动。开发是创造或者建立某种事物的行为,如一个功能模块或整个系统。而测试的重要目的是证实一个模块或者一个系统工作不正常。这两个活动之间有着本质的矛盾。因此,不管是程序员还是开发小组都应避免测试自己或者本组成员开发的功能模块。若条件允许,应当由独立于开发成员和客户的第三方来进行软件测试。但这并不是说程序员不能测试自己的程序,而且更加鼓励程序员进行调试,因为软件测试由独立测试机构承担有很多好处。独立测试可以避免软件开发者测试自己开发的软件,由于心理学上的问题,软件开发者难以客观、有效的测试自己的软件,要找出那些因为对问题的误解而产生的错误就更加困难。
(2)应尽早地和不断地进行软件测试。
应当把软件测试贯穿到整个软件开发的过程中,而不应该把软件测试看作是其过程中的一个独立阶段。因为在软件开发的每一环节都可能会产生意想不到的问题,如软件本身的抽象性和复杂性、各个开发阶段的多样性,以及不同人员之间的配合关系等。因此,要坚持各开发阶段的确认与评审,早发现错误,从而可以减少成本,提高软件质量。
(3)对测试用例要有正确的态度。
首先,测试用例应当由测试输入数据和与之对应的预期输出结果这两部分组成。测试以前应当根据测试的要求选择测试用例,以备测试过程中使用。其次,在进行测试用例的设计时,不仅要考虑合理的输入条件,更应该考虑不合理的输人条件。因此,需要用一些不合理的输入条件来发现更多的鲜为人知的软件缺陷。
(4)充分注意测试中的群集现象。
人以群分,物以类聚,软件测试也不例外,一定要充分注意软件测试中的群集现象,也可以称为“8020原则”。不要以为发现几个错误并且解决这些问题之后,就不需要测试了。反而这里是错误群集的地方,对这段程序要重点测试,以提高测试投资的效益。
(5)应当对每一个测试结果进行全面检查。一定要全面地、仔细地检查测试结果,但常常被人们忽略,导致许多错误被遗漏。
(6)严格执行测试计划,排除测试的随意性,以避免发生错误或者重复无效的工作。
(7)妥善保存测试用例、测试计划、测试报告和最终分析报告,以备回归测试及维护之用。
总之,软件测试更适宜被视为试图发现程序中错误的破坏性的过程。一个成功的测试,通过诱发程序发生错误,可以在这个方向上促进软件质量的改进。当然,最终人们还是要通过测试来人们相信:软件做了其应该做的,而没有做其不应该做的。在遵守以上原则的基础上进行软件测试,可以以最少的时间和人力找出软件中的各种缺陷,从而达到保证软件质量的目的。

1.1.4服装管理软件测试的划分
对于软件测试来说,从不同的角度来看,有不同的划分方法:
从是否执行程序的角度划分,可以分为静态测试和动态测试。其中软件的静态测试不要求在计算机上实际执行所测程序,主要以一些人工的模拟技术对软件进行分析和测试;而软件的动态测试是通过输入一组预先按照一定的测试准则构造的实例数据来动态运行程序,而达到发现错误的过程。
从是否关心软件内部结构和具体实现的角度划分,可以分为白盒测试、黑盒测试和灰盒测试。白盒测试是指按照程序内部的结构测试程序,通过测试来检测产品内部动作是否按照设计规格说明书的规定正常进行,检验程序中的每条通路是否都能按预定要求正确工作。黑盒测试是指在已知产品所应具有的功能,通过测试来检测每个功能是否都能正常使用,在测试时,把程序看作一个不能打开的黑盒子,它只检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能适当地接收输入数据而产生正确的输出信息,并且保持外部信息的完整性。灰盒测试,是介于白盒测试与黑盒测试之问的一种测试方法。可以这样理解,灰盒测试关注输出对于输人的正确性,同时也关注内部表现,但这种关注不像白盒那样详细、完整,只是通过一些表征性的现象、事件、标志来判断内部的运行状态,有时候输出是正确的,但内部其实已经错误了,这种情况非常多,如果每次都通过白盒测试来操作,效率会很低,因此需要采取这样的一种灰盒的方法。
从软件开发的过程按阶段划分,可以分为单元测试、集成测试、确认测试等。开始是单元测试,集中对用源代码实现的每一个程序单元进行测试,检查各个程序模块是否正确地实现了规定的功能。集成测试把已测试过的模块组装起来,主要对与设计相关的软件体系结构的构造进行测试。确认测试则是要检查已实现的软件是否满足了需求规格说明中确定了的各种需求,以及软件配置是否完全、正确。系统测试把已经经过确认的软件纳入实际运行环境中,与其他系统成份组合在一起进行测试。

1.2.1白盒测试的原理
1.2白盒测试
白盒测试也称结构测试或逻辑驱动测试,它是按照程序内部的结构测试程序,通过测试来检测产品内部动作是否按照设计规格说明书的规定正常进行,检验程序中的每条通路是否都能按预定要求正确工作。白盒测试把测试对象看做一个打开的盒子,允许测试人员利用程序内部的逻辑结构及有关信息,设计或选择测试用例,对程序所有逻辑路径进行测试。通过在不同点检查程序的状态,确定实际的状态是否与预期的状态一致。
白盒测试知道产品内部工作过程,可通过测试来检测产品内部动作是否按照规格说明书的规定正常进行,按照程序内部的结构测试程序,检验程序中的每条通路是否都有能按预定要求正确工作,而不顾它的功能,白盒测试的主要方法有逻辑驱动、基路测试等,主要用于软件验证。
软件人员使用白盒测试方法,主要想对程序模块进行如下的检查:
(1)保证一个模块中的所有独立路径至少被使用一次。
(2)对所有的逻辑判定,取“真”与取“假”的两种情况都至少测试一次。
(3)在上下边界及可操作范围内运行所有循环。
(4)测试内部数据结构的有效性。
白盒测试的测试方法有代码检查法、逻辑覆盖法、静态结构分析法、域测试、静态质量度量法、基本路径测试法、符号测试和程序变异等。
自盒测试法的覆盖标准有逻辑覆盖、循环覆盖和基本路径测试。其中逻辑覆盖包括语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、条件组合覆盖和路径覆盖等。

1.2.2逻辑覆盖
自盒法是穷举路径测试,在使用这一方案时,测试者必须检查程序的内部结构,从检查程序的逻辑着手,得出测试数据。但贯穿程序的独立路径数往往是天文数字,即使每条路径都测试了仍然可能有错误。这是因为:
(1)穷举路径测试决不能查出程序违反了设计规范,即程序本身是个错误的程序。
(2)穷举路径测试不可能查出程序中因遗漏路径而出错。
(3)穷举路径测试可能发现不了一些与数据相关的错误。
软件工程的总目标是充分利用有限的人力和物力资源,高效率、高质量、低成本地完成软件开发项目。在软件的测试过程中既然穷举测试不可行,为了能够节省时间和资源,提高测试效率,就必须要从数量极大的可用测试用例中精心地挑选少量的测试数据,使得这些数据能够达到最佳的测试效果,高效地揭露出隐藏的错误.因此就需要运用一些相关的技术。
逻辑覆盖就是以程序内部的逻辑结构为基础的来设计测试用例的白盒测试技术。它要求测试人员对程序的逻辑结构有清楚的了解,甚至要能掌握源程序的所有细节。由于覆盖测试的目标不同,逻辑覆盖又可分为:语句覆盖、判定覆盖、判定一条件覆盖、条件组合覆盖及路径覆盖。
1)语句覆盖
语句覆盖又称为点覆盖,就是设计若干个测试用例,当运行被测试的程序时,保证每一可执行语句至少执行一次。这种覆盖虽然能够使得程序中每个可执行语句都得到执行,但它是最弱的逻辑覆盖准,效果有限,必须与其他方法相互配合使用。
2)判定覆盖
判定覆盖又称为分支覆盖,就是设计若干个测试用例,当运行被测试的程序时,保证程序中每个判断的取真分支和取假分支至少经历一次。判定覆盖只比语句覆盖稍强一些,只用判定覆盖,还不能保证一定能查出在判断的条件中存在的错误。因此,还需要更强的逻辑覆盖准则去检验判断内部条件。
3)条件覆盖
条件覆盖就是设计若干个测试用例,当运行被测试的程序时,保证程序中每个判断的每个条件的可能取值至少执行一次,即每个判定的每个条件应取到各种可能的值。
条件覆盖深入到判定中的每个条件,但可能不能满足判定覆盖的要求。
4)判定一条件覆盖
判定一条件覆盖就是设计足够的测试用例,使得判断中每个条件的所有可能取值至少执行一次,同时每个判断本身的所有可能判断结果至少执行一次,即是要求各个判断的所有可能的条件取值组合至少执行一次。
从表面上来看,判定一条件覆盖测试了所有条件的取值。但是事实并非如此。往往某些条件掩盖了另一些条件,因此,会遗漏某些条件取值错误的情况。为彻底地检查所有条件的取值,需要将判定语句中给出的复合条件表达式进行分解,形成由多个基本判定嵌套的流程图。这样就可以有效地检查所有的条件是否正确了。
5)多重条件覆盖
多重条件覆盖就是设计足够的测试用例,当运行被测试的程序时,保证每个判断的所有可能的条件取值组合至少执行一次。
多重条件覆盖是一种相当强的覆盖准则,它可以有效地检查各种可能的条件取值的组合正确与否。多重条件覆盖不但可覆盖所有条件的可能取值的组合,还可覆盖所有判断的可取分支,但有的路径也可能会遗漏掉,因此,还不完全的测试。
6)路径测试
路径测试就是设计足够的测试用例,覆盖程序中所有可能的路径,即使程序中每一条可能的路径至少执行一次。路径测试是一种最强的覆盖准则。但是由于程序中的路径数目往往很大,真正做到完全覆盖几乎不可能,因此必须把覆盖路径数目压缩到一定限度。

1.2.3基本路径测试法
白盒测试的测试方法有代码检查法、逻辑覆盖法、静态结构分析法、域测试、静态质量度量法、基本路径测试法、符号测试和程序变异等,其中运用最为广泛的是基本路径测试法。
基本路径测试法是在程序控制流图的基础上。通过分析控制构造的环路复杂性,导出基本可执行路径集合,从而设计测试用例的方法。设计出的测试用例要保证在测试中程序的每个可执行语句至少执行一次。
基本路径测试法的步骤如下。
1)画出控制流图
程序的控制流图是描述程序控制流的一种图示方法,可将流程图映射到一个相应的流图(假设流程图的菱形决定框中不包含复合条件)。流图只有两种图形符号:圆圈和箭头。流图中的每一个圆圈称为流图的结点,代表一个或多个无分支的语句或源程序语句;流图中的箭头称为边,表示控制流的方向,在选择或多分支结构中分支的汇聚处,即使没有执行语句也应该有~个汇聚结点.
控制流图中一条边必须终止于一个结点,即使该结点并不代表任何语句(如if-else—then结构)。由边和结点限定的范围称为区域,当对区域计数时,图形外的区域也应记为一个区域。
如果判定中的条件表达式是复合条件时,即条件表达式是由一个或多个逻辑运算符(OR,AND,NAND,NOR)连接的逻辑表达式,则需要改复合条件的判定为一系列只有单个条件的嵌套的判定。例如对应图11—5(a)的复合条件的判定,应该画成如图1卜5(b)所示的控制流图。条件语句ifaORb中条件a和条件b各有一个只有单个条件的判定结点。
2)计算环路复杂度
在进行程序的基本路径测试时,程序的环路复杂性是一种为程序逻辑复杂性提供定量测度的度量方法,该方法给出了程序基本路径集合中的独立路径条数,这是确保程序中每个可执行语句至少执行一次所必需的测试用例数目的上界。一条独立路径是指,和其他的独立路径相比,至少引入一个新处理语句或一个新判断的程序通路。
如在图11—4所示的控制流图中,一组独立的路径是:
路径1:1-9
路径2:1-2—4-8—1—9
路径3:1—2—3—57—8—1—9
路径4:卜2-3—6—7—8一l一9
路径1、路径2、路径3、路径4组成了图1卜4所示控制流图的一个基本路径集。只要设计出来的测试用例能够确保这些基本路径的执行,就可以使得程序中的每个可执行语句至少执行一次,也就是每个条件的真和假分支都能够进行测试。当然,控制流图中的基本路径集不是唯一的,对于给定的控制流图,不同的人可能会得到不同的基本路径集。
有以下三种方法计算环路复杂度:
①将环路复杂性定义为控制流图中的区域数。
②把流图G的环路复杂度定义为V(G)一E—N+2,其中E是流图中边的数量,N是流图中结点的数量。
③或者把流图G的环路复杂度定义为V(G)一P+1,其中P是流图G中判定结点的数量。
图11-4所示的控制流图有4个区域,其环路复杂性为4。它是构成基本路径集的独立路径数的上界,因此,可以据此得到应该设计的测试用例的数目。
3)准备和导出测试用例
为了确保基本路径集中的每一条路径的执行,可以根据上面获得的独立路径,去设计输入数据,使程序分别执行到上面的各条路径。

1.3.1黑盒测试概念
1.3黑盒测试
黑盒测试也称功能测试或者数据驱动测试,它是指在已知产品所应具有功能的情况下,通过检测每个功能是否都能够正常使用的测试方法。软件的黑盒测试意味着测试要根据软件的外部特性进行。也就是说,在测试时,测试人员完全不考虑程序内部的逻辑结构和内部特性,而是把程序看作一个不能打开的黑盒子,测试者在程序接口进行测试,它只检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能适当地接收输入数据而产生正确的输出信息,并且保持外部信息的完整性。
黑盒测试方法主要是为了发现是否有不正确或遗漏了的功能?是否有数据结构错误或外部信息(例如数据文件)访问错误?输入能否被正确地接受?能否输出正确的结果?系统在性能上是否能够满足要求?是否有初始化或终止性错误等。因此,用黑盒测试来发现程序中的错误时,必须在所有可能的输入条件和输出条件中确定测试数据,检查程序是否都能产生正确的输出。
黑盒测试方法主要有等价类划分、边值分析、因果图、错误推测等。

1.3.2等价类划分
在很多时候,某些数据输入后得到的输出结果是相同或者相似的,而与其他一些数据输入后得到的结果不相近,从而可以把输入数据划分成若干部分(子集),在该子集合中,各个输入数据对于揭露程序中的错误都是等效的,然后从每一个子集中选取少数具有代表性的数据作为测试用例,从而减少了输入数据量提高了效率,称之为等价类方法。该方法是一种重要的、常用的黑盒测试用例设计方法。
1.等价类的分类
等价类划分可有两种不同的情况:有效等价类和无效等价类。
1)有效等价类
有效等价类是指对于程序的规格说明来说是合理的、有意义的输入数据构成的集合。利用有效等价类可检验程序是否实现了规格说明中所规定的功能和性能。
2)无效等价类
与有效等价类恰巧相反,无效等价类指对程序的规格说明是不合理的或无意义的输入数据所构成的集合。对于具体的问题,无效等价类至少应有一个,也可能有多个。
由于软件不仅要能够接收合理的数据,也要能够经受得起意外的考验以保证软件具有更高的可靠性,因此,在进行测试时,要同时考虑这两种等价类。
2.等价类的划分原则
在进行等价类划分时应该满足下列的原则:
(1)如果输入数据规定了取值范围或个数,则可以划分一个有效等价类和两个无效等价类。
例如,在软件的规格说明中,输入值是学生成绩,范围是0~100,则有效等价类是“0≤成绩≤100”;两个无效等价类是“成绩<o”及“成绩>100”。
(2)在规定了输入值的集合或必须是“XX类型”时,可以划分一个有效等价类和一个无效等价类。
例如,在某程序语言中规定变量标识符为“以字母开头的字符串”,那么有效等价类就是所有以字母开头的字符串,而不以字母开头的字符串归于无效等价类。
(3)在输入值为一个条件数据时,可以划分一个有效等价类和一个无效等价类。
例如,“计算机专业的学生必须……”,则考虑计算机专业的学生为有效等价类,非计算机专业的学生则为无效等价类。
(4)在输入一组(,z个)值且伴有判断情况(m种)时,可划分7"/或m个有效等价类和一个无效等价类。
在划分等价类时,划分等价类重要的是集合的划分,划分为互不相交的一组子集,而子集的并集是整个集合,即需要保证划分的完备性和无冗余性。
3.测试用例的设计
在确定并划分出所有的等价类之后,可以按以下原则来选择测试用例:
(1)为每个等价类规定一个唯一的编号。
(2)设计一个新的测试用例,使其尽可能多地引入未被引入的有效等价类。重复这一步,直到所有等价类都被完全使用。
(3)设计一个新的测试用例,使其仅引入一个未被引入的无效等价类。重复这一步,直到所有无效等价类都被完全使用。
上述原则中,原则(2)完全是为了把测试工作量减到最小,原则(3)则可把多个错误分开。

1.3.3边界值分析
由于在等价类划分方法的输入中,选择的是一些具有代表性的数据而不是全部数据作为输入,所以有些会引起错误的特殊数据未被选择就在所难免。为此,就引入边界值分析方法来作为等价类划分方法的有力补充。之所以把这种方法称为边界值分析法,是由于这类数据往往集中在各个划分好的等价类的边界值附近,而且在这种方法中,不单要考虑输入域的边界也要考虑输出域的边界。
边界值分析法选值的总体指导原则是应当选择刚好等于,稍微大于和小于边界值的值进行测试,具体方法如下:
(1)当输入域为一个值的范围时,选择范围的边界值和略微超越边界值的值。
(2)当输出域判断为一个值的范围时。使用方法(1)。
(3)当输入域规定了值的个数时,选择min,min一1,max,max+1。
(4)当输出域判断为限定个数的值时,使用方法(3)。
(5)当输入输出域判断依据一个内部数据结构时,使用改数据结构的边界值。
(6)当输入输出域判断依据一个有序列时,选择有序列的第一个和最后一个元素。
(7)除了规定的范围,考虑其他会存在的未明示的可能值。
用边界值分析法来设计测试用例需要对每个边界值建立一个新的用例。

1.3.4错误推测和因果图方法
在黑盒测试中,有些点虽然不是一个主要的输入或者输出接口,但是它很容易导致错误,或者在系统以前版本中某个点会反复出现错误。针对这种情况,设定一些测试用例来监视这些容易出错的地方,就能有效的提高错误产生点的判断效率。由于这种方法是一种根据可能出现的错误来进行预推测,因此称为错误推测方法。
错误推测方法设计测试用例时,按照可能发生错误的情况去书写测试用例,这样就能主动监测那些容易出错的点。
因果图方法是指将各个数据联系在一起来进行考虑,从而引申出多种组合,这时候有些单个数据完好的功能就可能出现错误。在进行数据组合时,主要是根据他们之间的逻辑关系,使用同一组数据搭配不同的线路来测试不同的路径。

1.4.1什么是单元测试
1.4单元测试
单元测试又称模块测试,是针对软件设计的最小单位——程序模块来进行的正确性检验的工作。单元测试的目的在于发现各模块内部可能存在的各种差错。在传统的结构化编程语言(例如C)中,要进行测试的单元一般是函数或子过程;在面向对象的语言中,要进行测试的基本单元是类。
通常而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定模块的行为。单元测试一般是由程序员自己来完成,程序员有责任编写功能代码,同时也就有责任为自己的代码编写单元测试。执行单元测试,就是为了证明这段代码的行为和期望的一致。单元测试需要从编写单元测试。执行单元测试,就是为了证明这段代码的行为和期望的一致。单元测试需要从程序的内部结构出发设计测试用例,多个模块可以平行地独立进行单元测试。
在单元测试时,测试者需要依据详细设计说明书和源程序清单,了解该模块的输入输出条件和模块的逻辑结构,因此,主要是采用白盒测试辅之以黑盒测试的形式进行,使之对任何合理的输入和不合理的输入,都能鉴别和响应。

1.4.2单元测试的内容
在单元测试中,主要在5个方面对被测模块进行检查。
1.模块接口测试
在单元测试开始时,应对通过所有被测模块的数据流进行测试。
测试项目包括:
(1)模块输入参数的数目与模块形式参数数目是否相同。
(2)模块各输入的参数类型和属性与对应的形参类型和属性是否一致。
(3)传到被调用模块的实参的数目与被调用模块形参的数目是否相同。
(4)传到被调用模块的实参的类型和属性与被调用模块形参的类型和属性是否一致。
(5)引用内部函数时,实参的次序和数目是否正确。
(6)用于输入的变量有没有改变。
(7)是否引用了与当前人口无关的参数。
(8)在经过不同模块时,全局变量的定义是否一致。
(9)使用外部资源时,是否检查可用性并及时释放资源,如内存、文件、硬盘、端口等。
在做内外存交换时要考虑:
(1)文件属性是否正确。
(2)缓冲区容量与记录长度是否匹配。
(3)0PEN与CI。oSE语句是否正确。
(4)在进行读写操作之前是否打开了文件。
(5)在结束文件处理时是否关闭了文件。
(6)I/0错误是否检查并做了处理。
2.局部数据结构测试
模块的局部数据结构是最常见的错误来源,应设计测试用例以检查以下各种错误:
(1)不正确或不一致的数据类型说明。
(2)变量名拼写错或书写错。
(3)使用尚未赋值或尚未初始化的变量。
(4)错误的初始值或错误的默认值。
(5)全局数据对模块的影响。
(6)不一致的数据类型。
(7)非法指针。
(8)数组越界等。
3.路径测试
由于在测试时不可能做到穷举测试,所以在单元测试时要根据自盒测试和黑盒测试用例设计方法设计测试用例,对模块中重要的执行路径进行测试。路径测试是为了检查由于计算错误、判定错误、控制流错误导致的程序错误。重要的执行路径指那些由于控制较复杂而易错的路径和处在完成单元功能的算法、控制、数据处理等重要位置的执行路径,有选择地对执行这些路径进行测试是一项重要的任务。
在进行路径测试时,应该做到:
(1)应当选择适当的测试用例,对模块中重要的执行路径进行测试。
(2)应当设计测试用例查找由于错误的计算、不正确的比较或不正常的控制流而导致的错误。
(3)应当对基本执行路径和循环进行测试可以发现大量的路径错误。
4.错误处理测试
错误处理路径是指可能引发错误处理的路径及进行错误处理的路径。当错误出现时,错误处理程序就需要重新安排执行路线,或通知用户处理,或干脆停止执行使程序进入一种安全等待状态。
一般软件错误处理测试应考虑下面几种可能的错误:
(1)出错的描述是否难以理解。
(2)出错的描述是否能够对错误定位。
(3)对错误条件的处理正确与否。
(4)显示的错误与实际的错误是否相符。
(5)在对错误进行处理之前,错误条件是否已经引起系统的干预等。
5.边界测试
软件常常会在边界上出错,因此,需要进行边界测试。边界测试是单元测试中最后的任务。在进行边界测试时,需要特别注意数据流、控制流中刚好等于、大于或小于确定的比较值时出错的可能性,并在这些地方仔细地选择合适的测试用例来认真加以测试。
此外,如果对模块运行时间有特殊要求的话,还需要进行专门的关键路径测试,以确定最坏情况下和平均意义下影响模块运行时间的因素。
边界测试要检查的内容具体包括:
(1)普通非法数据是否正确处理。
(2)普通合法数据是否正确处理。
(3)在押次循环的第0次、第1次、第抑次是否有错误。
(4)边界内最接近边界的合法数据是否正确处理。
(5)边界外最接近边界的非法数据是否正确处理。
(6)判断或运算中取最大最小值时是否有错误。
(7)数据流、控制流中刚好等于、大于和小于确定值时是否出现错误等。

1.4.3单元测试过程
由于单元测试针对程序模块,而程序模块单元往往并不是一个独立可运行的程序,因此,在单元测试中,测试用例的设计与测试集合的准备是至关重要的。在考虑进行模块测试时,就需要考虑到它和外界其他模块的联系,可以用一些辅助模块去模拟与被测模块关联的其他模块。这些模块包括一个驱动模块和若干个桩模块。
1.驱动模块
驱动模块相当于所测模块的主程序,它接收测试数据,把这些测试数据传送给被测模块,最后再输出实测结果。
2.桩模块
桩模块由被测模块调用,用以代替由被测单元所调用的模块的功能,返回适当的数据或进行适当的操作使被测单元能继续运行下去,同时还要进行一定的数据处理,如打印人口和返回等,
以便检验被测模块与其下级模块的接口。
驱动模块和桩模块在软件开发结束后就不使用了,但是驱动模块和桩模块为程序单元的执行构成了一个完整的环境,为了单元测试,两者都要进行开发。驱动模块用以模拟被测单元的上层模块,测试执行时由驱动模块调用被测单元使其运行,桩模块模拟被测单元执行过程中所调用的模块,测试执行时桩模块使被测单元能完整闭合地运行。
在进行单元测试时,可以按照下列的步骤进行处理。
(1)构造测试用例的运行环境,即确定用例运行的前提条件,明确被测模块所需的程序环境
(全局变量赋值或初始化实体),启动测试驱动,设置桩,调用被测模块,设置预期输出条件判断。
(2)设计黑盒测试用例,即接口测试用例,这可以按照下列内容顺序进行:
①设计基本功能测试用例,证明被测模块至少在某种正常情况下能够运行了。
②设计功能正面测试用例,找出被测模块对于设计要求的正确输入可能做出的不正确处理。
③设计功能反面测试用例,找出被测模块对于设计要求的错误输入可能做出的不正确处理。
④设计性能测试用例,找出模块对于设计要求的性能可能做不到的错误。
(3)设计白盒测试用例.即覆盖测试用例,找出模块内部控制结构和数据使用可能存在的问题。
(4)恢复测试环境(包括清除桩)。
由于驱动模块和桩模块不需要与最终产品以其交付用户,因此驱动模块和桩模块的设计要尽量简单,避免因其错误而干扰被测单元的运行及测试结果判断。

1.5.1什么是集成测试
1.5集成测试
实践表明,虽然一些模块能够单独地工作,但并不能保证连接起来一定能正常的工作。程序在某些局部模块反映不出来的问题,很可能在全局上暴露出来,影响功能的实现,因此需要进行集成测试。
集成测试,也称为联合测试或组装测试,是单元测试的逻辑扩展。它是指在单元测试的基础上,将所有模块按照设计要求组装成为子系统或系统时进行的测试。
集成测试的最简单的形式是把两个已经测试过的单元组合成一个组件,并且测试它们之间的接口。在现实方案中,许多单元组合成组件,而这些组件又聚合成程序的更大组件。因此可以说组件就是多个单元的集成聚合。
在进行集成测试时需要考虑的问题是包括:
(1)一个模块的功能是否会对另一个模块的功能产生不利的影响。
(2)在把各个模块集成起来时,模块接口之间传递的数据是否会丢失。
(3)模块中各个功能组合起来,能否达到预期的要求。
(4)全局数据结构是否会出现问题。
(5)单个模块的误差累积起来,是否会放大,从而达到不能接受的程度。

1.5.2集成测试策略
在软件开发中,不管采用什么样的模式,系统的开发总是从一个一个小的软件单元做起的,这些软件单元只有经过集成才能形成一个有机的整体。所以,所有的软件项目都不能摆脱系统集成这个阶段。
集成测试是在单元测试的基础上,测试在将所有的软件单元按照规约说明的要求组装成模块、子系统或系统的过程中各部分功能是否达到或实现相应技术指标及要求。也就是说,在集成测试之前,需要进行集成测试的单元已经通过了单元测试,达到了要求。
集成测试的目的是为了测试软件单元的组合能否正常工作,以及与其他组的模块能否集成起来工作。此外,集成测试还要测试构成系统的所有模块组合能否正常工作。集成测试所持的主要标准是软件的设计规约说明,任何不符合该说明的程序模块行为都应该加以记载并上报。
在软件测试中,集成测试是一个很重要的测试过程,在进行测试之前必须进行精心的计划,并与单元测试的完成时间协调起来。
在制定测试计划时,应考虑如下因素:
(1)采用何种模块集成方式来进行集成测试。
(2)集成测试过程中各个模块的连接顺序。
(3)模块代码的编制和测试进度是否与集成测试的顺序一致。
(4)测试过程中是否需要专门的硬件设备。
解决了上述问题之后,就可以列出各个模块的编制、测试计划表,标明每个模块单元测试完成的日期、首次集成测试的日期、集成测试全部完成的日期、需要的测试用例和所期望的测试结果。
在集成测试过程中的两个重要的里程碑是功能冻结和代码冻结的确定。
1)功能冻结
功能冻结是指经过测试,符合设计要求,确认系统功能和其他特性均不再做任何改变。
2)代码冻结
在理想情况下,对无错误的代码需要进行冻结。但实际上,代码冻结只标志系统的当前版本的质量已达到预期的要求,冻结程序的源代码,不再对其做任何修改。

1.5.3集成测试方案
集成测试的实施方案有很多种,如自顶向下集成测试、自底向上集成测试、核心集成测试、三明治集成测试、分层集成测试、基于使用的集成测试等。此处仅对一些常用和实践证实有效的方案进行讨论。

1.自项向下集成测试(Top—DownIntegration)
自顶向下集成方式将模块按系统程序结构,沿控制层次自顶向下进行组装,即从主控模块(主程序)开始沿控制层向下移动,把模块一一组合起来。自顶向下的集成测试在测试过程中可以较早地验证主要的控制和判断点。
这种集成测试可以分以下两种原则进行。
1)深度优先原则
按照系统程序结构,用一条主控制路径将所有模块组合起来。
2)宽度优先原则
从上至下逐层组合所有下属模块,在每一层水平地集成测试沿着移动。
选用深度优先原则进行组装,可以首先实现和验证一个完整的软件功能。
自顶向下集成测试过程分以下五个步骤:
(1)用主控模块作为测试驱动程序,其直接下属模块用承接模块来代替。
(2)根据所选择的集成测试原则(深度优先或宽度优先),每次用实际模块代替下属的承接模块。
(3)在组合每个实际模块时都要进行测试。
(4)完成一组测试后再用一个实际模块代替另一个承接模块。
(5)可以进行回归测试,即重新再做所有的或者部分已做过的测试,以保证不引入新的错误。

2.自底向上集成测试(Bottom—UpIntegration)
自底向上集成方式从程序模块结构中最底层的模块开始组装和测试。因为模块常常是自底向上进行组装的,对于一个给定层次的模块来说,它的子模块及下属模块已经组装并测试完成,所以不再需要桩模块。在模块的测试过程中需要从子模块得到的信息可以直接运行子模块得到。
自底向上集成测试大致包括如下步骤:
(1)按照体系结构设计规约,明确需要进行测试的模块。对被测模块按照其性质进行分层,在周一层次上的测试可以并行进行,然后安排测试活动的先后顺序,制定测试计划。
(2)在(1)的基础上,按先后关系,将软件单元集成为模块,并对集成过程中出现的问题进行测试。对较大的模块,可先将其划分为几个子模块,然后再集成为一个较大的模块。
(3)将各软件模块集成为子系统,并检测各自子系统是否能正常工作。
(4)将各子系统集成为最终用户系统,测试各分系统能否在最终用户系统中正常工作。
自底向上的集成测试方案是测试实践中最常用的测试方法,其优点是:管理方便、测试人员能较好地锁定软件故障所在位置。但它需要测试人员在全部软件单元实现之前完成核心软件部件的集成测试。

3.核心系统优先集成测试
核心系统优先集成测试法是指先对系统中的核心部件进行集成测试,在测试通过的基础上再按外围部件的重要程度逐个集成到核心系统中。每次加人一个外围软件部件都会产生一个产品基线,直至形成最终稳定的软件产品为止。
核心系统优先集成测试法对应的集成过程是一个逐渐趋于闭合的螺旋形曲线,代表产品逐步定型的过程,其具体步骤如下:
(1)对系统中的各个核心部件进行单独的、充分的测试,必要时使用驱动模块和桩模块。
(2)对系统中的全部核心部件一次性集合到被测系统中,解决集成中出现的各类问题。
(3)按照各外围软件部件的重要程度以及模块间的相互制约关系,确定外围部件集成到核心系统中的先后顺序。当然,在外围部件添加到核心系统之前,应先完成内部的模块级的集成测试。
(4)按先后顺序不断把外围部件加入核心系统中,排除外围部件集成中出现的问题,形成最终的用户系统。
核心系统优先集成测试方法对于快速软件开发很有效果,适合较复杂系统的集成测试,能够保证一些重要的功能和服务的实现。其缺点是很多系统难以明确区分核心部件和外围部件。
以上介绍的几种常见的集成测试方案都各有优点,一般来讲,在现代复杂软件项目集成测试过程中,通常是把各种方案结合在一起以达到良好的测试效果。

1.6.1确认测试的内容
1.6确认测试
通过集成测试之后,就已经按照设计要求把所有的模块组装成一个完整的软件系统。此时,模块之间的接口错误已经基本排除了,接着就应该进一步验证系统的有效性,这就是确认测试的任务,即软件。已完全组装起来,接口方面的错误也已排除,确认测试即可开始。
确认测试又称有效性测试,它是运用黑盒测试的方法,验证被测软件是否满足需求规约说明书中所列举出来的需求。确认测试的目的是向未来的用户表明系统的功能和性能如同用户所合理期待的那样。而软件系统的功能和性能要求在软件需求规约说明书中已经进行过明确规定,它就是软件确认测试的基础。
确认测试的内容包括以下几方面。
1)安装测试
在安装软件系统时,会有多种选择。要分配和装入文件与程序库,布置适用的硬件配置,进行程序的连接。而安装测试的目的不是查找软件错误,而是要查找出在这些安装过程中出现的错误。
2)功能测试
功能测试是依据需求文档来测试软件系统的功能是否正确。由于正确性是软件最重要的质量因素,所以功能测试必不可少。
3)性能测试
性能测试是测试软件系统处理事务的速度,一方面是检验性能是否符合需求;另一方面是为了得到某些性能数据以供参考。
特别是对于实时系统或嵌人式系统,软件只满足要求的功能而达不到要求的性能是不可接受的,因此还需要进行性能测试。性能测试可以出现在测试过程的各个阶段,甚至在单元层次上,也可以进行性能测试。
4)安全性测试
安全性测试是测试软件系统防止非法人侵的能力,及系统有无漏洞。为此要了解破坏安全性的方法和工具,并设计一些模拟测试用例对系统进行测试,力图破坏系统的保护机构以进入系统。
5)兼容性测试
兼容性测试主要想验证软件产品在不同版本之间的兼容性。基本的兼容性测试有两类:向下兼容和交错兼容。向下兼容测试是测试软件的新版本保留它早期版本的功能的情况;而交错兼容测试主要是验证共同存在的两个不同但相关的产品之间的兼容性。
6)可使用性测试
可使用性测试主要从使用的合理性、方便性等角度对软件系统进行检查,以发现人为因素或使用上的问题。
7)文档测试
文档测试是检查用户文档(如用户手册)的清晰性。

1.6.2确认测试的基本方法
在确认测试阶段,首先要进行有效性测试以及软件配置复审,然后进行验收测试和安装测试,在通过了专家鉴定之后,才能成为可交付的软件。
1.进行有效性测试
有效性测试是在模拟的环境(可能就是开发的环境)下,运用黑盒测试的方法,验证被测软件是否满足需求规格说明书列出的需求。进行有效性测试时,首先需要根据要求制定测试计划,规定要做测试的种类。还需制定一组测试步骤,描述具体的测试用例。通过实施预定的测试计划和测试步骤来确定软件的特性与需求是否相符,以确保满足所有的软件的功能需求、达到所有的软件性能需求,并且所有的文档都是正确且便于地使用。此外,对其他的软件需求,例如兼容性、可移植性、可维护性、出错自动恢复等,也都要进行测试,确认这些性质是否得到满足。
2.软件配置复查
确认测试的另一个重要环节是配置复审。复审的目的在于保证软件配置齐全、分类有序,并且包括软件维护所必需的细节。
除了按照合同规定的内容和要求,由人工进行软件配置审查外,在确认测试的过程中,应当严格遵守用户手册和操作手册中规定的使用步骤,以便检查相关文档资料的正确性和完整性,并仔细记录发现的错误和遗漏,适当地进行补充和改正。
3.a测试和8测试
在软件交付使用之后,用户将如何实际使用程序,对于开发者来说是无法预测的。例如,用户可能错误的理解命令,或提供一些奇怪的数据组合,亦可能对设计者自认明了的输出信息迷惑不解等。因此,软件是否真正满足最终用户的要求,应由用户进行一系列验收测试。验收测试既可以是非正式的测试,也可以是有计划的、系统性测试。但是一个软件产品,可能拥有众多的用户,不可能让每个用户都来进行验收,因此,往往采用称为d、lB测试的方法,以发现可能只有最终用户才能发现的错误。
d测试是由一个用户在开发环境下进行的测试,也可以是软件开发公司组织内部人员模拟各类用户行对即将面市软件产品(称为旺版本)进行的测试。a测试的关键在于尽可能逼真地模拟实际运行环境和用户对软件产品的操作并尽最大努力涵盖所有可能的用户操作方式,并在测试中试图发现错误并修正。a测试人员是除开产品开发人员之外首先见到产品的人,他们提出的功能和修改意见是特别有价值的。
经过a测试调整的软件产品称为p版本。p测试是由软件的多个用户在一个或多个用户的实际使用环境下进行的测试。与a测试不同的是,开发者通常不在测试现场。在B测试中,用户需要记录所遇到的一切问题,并要求用户报告异常情况、提出批评意见。开发者在综合用户的报告之后,做出修改,最后将软件产品交付给全体用户使用。8测试着重于产品的支持性,包括文档、客户培训和支持产品生产能力,因此,只有当a测试达到一定的可靠程度时,才能开始B测试。
4.确认测试结果
在全部确认测试的测试用例运行完后,就可以对软件系统的测试结果进行确认,软件确认测试的结果有两种可能:
(1)测试结果与预期的结果相符,这说明软件的这部分功能和性能指标满足软件需求说明的要求,用户可以接受。
(2)测试结果与预期的结果不符,这说明软件的这部分功能或性能特征不满足软件需求说明的要求,用户无法接受。此时,需要开列一张软件各项缺陷表或软件问题报告,通过与用户的协商,解决所发现的缺陷和错误。

1.7面向对象的服装管理软件测试
面向对象技术在软件工程中的推广使用,使得传统的测试技术和方法受到了极大的冲击。对面向对象技术所引入的新特点,传统的测试技术已经无法有效地进行测试。对面向对象软件的测试,测试策略或方法都需要出现相应的变革或更新。
本节结合传统的测试技术,针对面向对象技术新特性在测试中所引发的问题,介绍了相关测试方法、理论和模型。首先,以软件工程中面向对象软件开发模式为参考,分别在面向对象分析,面向对象设计,面向对象编程三个阶段,依据各阶段的地位,作用,实现目标,具体阐述测试目的和应该注意的测试点。其次,依照传统的三个测试步骤:单元测试,集成测试,确认测试,借鉴传统测试方法有用的部分,论述如何有效的对面向对象软件进行测试。最后,对现有测试方法进行总结。

1.7.1面向对象测试与传统测试技术的区别
就测试目的而言,面向对象软件开发中测试的目标与以往传统的测试目标是完全相同的,都是为了确保软件能够正确地执行预定的功能。测试过程都包括了测试计划、测试用例设计、测试运行、测试结果分析。面向对象的测试也可以分为单元测试、集成测试、确认测试三个阶段,确认测试是对系统的功能和性能进行整体测试的过程,不涉及软件的具体实现方法,因而这个阶段的测试与系统使用的开发方法无关,日J以采用传统的测试万法进行。
涉及系统开发方法的测试集中在单元测试和集成测试这两个阶段,只要寻找出在这两个阶段中面向对象测试与传统测试的差别,就能够比较容易地进行面向对象的测试。以往采用的是过程性的测试方法,程序单元即为功能单元,系统由一系列相关联的序单元构成,可以认为程序具有单一入口和单一出口,程序之间的关系是调用关系。而面向对象的系统由一些相互关联的对象构成,对象之间靠消息传递信息,对象由数据和服务组成。它往往比采用传统方法开发的程序单元要庞大。并且采用面向对象的方法具有更高程度的抽象性。虽然系统是由对象构成,但在程序中的基本单元却是“类”,它是对象的抽象描述,对象是类的实例。另外类还具有继承和多态等结构。这些程序结构和实现机制的差别造成了测试方法的差异。类是对象经过抽象后的产物,不能直接运行,需要类实例化后形成的对象。这两点是类与传统意义上的程序模块之间的截然不同之处,也就造成两种测试方法的不同。在传统的软件测试中,测试过程要求与具体的应用环境尽量相结合,与应用环境结合越紧密,其测试的结果越可靠。但在面向对象的软件测试中,作为基本程序单元的类是一个可以应用于许多不同应用软件中的独立部件,其复用的程度高,要求不需了解任何实现细节就能复用。因此对类的测试要求尽量与具体应用环境相独立,与应用环境越独立,其测试的结果越可靠。面向对象的测试与传统测试的差异主要由于程序实现机制的不同而造成,“类”是面向对象程序的主要机制,对基本程序单元“类”的测试贯穿着单元测试和集成测试两阶段,解决了类的测试问题也就解决面向对象测试中的关键问题。
总之,面向对象软件测试的策略较传统测试方法有了很大不同,测试的焦点也从过程构件移向类。传统的结构化软件测试技术受到了前所未有的挑战,针对面向对象软件的开发特点,应该有一种新的测试模型。

1.7.2面向对象特征对软件测试的影响
从1982年在美国北卡罗来纳大学召开首次软件测试的正式技术会议至今,软件测试理论迅速发展,并相应出现了各种软件测试方法,使软件测试技术得到极大地提高。然而,一度实践证明行之有效的软件测试对面向对象技术开发的软件多少显得有些力不从心。尤其是面向对象技术所独有的多态、继承和封装等新特点,产生了传统语言没计所不存在的错误可能性,或者使得传统软件测试中的重点不再显得突出,或者使原来测试经验认为和实践证明的次要方面成为主要问题。
面向对象软件将传统软件中的一个过程或一个方法内的复杂性转移到对象之间的交互中。面向对象语言一些本质特征形成了如下的一些新的故障、错误风险。
1)基本功能模块
在面向对象系统中,系统的基本构造单元是封装了数据和方法的类和对象,而不再是一个个能完成特定功能的功能模型。每个对象有自己的生存期,有自己的状态。消息是对象之间相互请示或协作的途径,是外界使用对象方法及获取对象状态的唯一方式。对象的功能是在消息的触发下,由对象所属类中定义的方法与相关对象的合作共同完成,并且对象在不同状态下对消息的响应可能完全同。工作过程中,对象的状态可能被改变,产生新的状态,即发生状态的转移。对象中的数据和方法是一个有机的整体,在软件测试过程中,不能仅仅检查输入数据产生的输出结果是否与预期结果相吻合,还要考虑对象的状态变化。因此,除了要对对象的状态与方法间的相互影响进行测试,还要进行状态测试。
2)系统的功能实现
在面向对象系统中,系统的功能体现在对象间的协作上,而不再是简单的过程调用关系。面向对象程序的执行实际上是执行一个由消息连接起来的方法序列,方法的实现与所属对象本身的状态有关,各方法之间可能有相互作用。为实现某一特定的功能,可能要激活调用属于不同对象类的多个成员函数,形成成员函数的启用链。因此,基于功能分解的自顶向下或自底向上的集成测试策略不适用于面向对象软件系统的测试。
3)封装对测试的影响
封装是指在词法单位之中或之间决定名字可见性的访问控制机制。它支持信息的隐蔽和模块化,有助于防止全局变量访问的问题。尽管封装不会直接促成错误的发生,它却给测试带来了障碍。封装使对象的内部状态隐蔽,如果类中未提供足够的存取函数来表明对象的实现方式和内部状态,则类的信息隐蔽机制将给测试带来困难。
4)继承对测试的影响
继承也是面向对象语言中的一个本质特征。继承可用于一般与特殊关系,并且方便编码。但继承削弱了封装性,产生了类似于非面向对象语言中全局数据的错误风险。由于继承的作用,一个函数可能被封装在具有继承关系的多个类中,子类中还可以对继承的特征进行覆盖或重定义。
5)多态对测试的影响
多态性是指一个引用可以与多个对象绑定的能力。多态能减少代码的复杂性和规模,同时还可以实现动态绑定。但依赖于不规则的类层次的动态绑定可能产生编程人员没有想到的结果。某些绑定能正确的工作但并不能保证所有的绑定都能正确地运行。以后绑定的对象可能很容易将消息发送给错误的类,执行错误的功能,还可能导致一些与消息序列和状态相关的错误。

1.7.3面向对象测试中所用到的术语
本节将介绍在测试期间使用到的模型元素。
对上图中各元素说明如下:
(1)测试构件是系统中可以独立测试的一个部分。一个测试构件可以是一个对象、一组对象甚至是一个或多个子系统。
(2)故障,也称为缺陷或者错误,是可能引起构件异常行为的设计或是编码错误。
(3)错误状态是系统在执行过程中一个故障的表示。一个或是多个故障导致错误状态的出现,最终可能会导致整个系统的失效。
(4)失效是规格说明和实际功能之间的偏差。一个失效由一个或是多个错误状态触发,但并不是所有的错误状态都会触发失效。
(5)测试用例是一组输人数据和期望结果的集合,它们的目的是为了在使用测试构件过程中导致测试构件失效和发现测试构件故障。
(6)测试桩是测试构件的部分实现。对单一构件或组合构件执行测试用例,都要求被测构件是与系统其余部分独立开来。测试桩程序和测试驱动程序经常用来替换与被测系统相关联的部分。测试驱动是一个构件的部分实现,它依赖于被测试构件。测试桩和测试驱动使得待测构件在测试中可以与系统其余部分相互独立。测试驱动程序模拟了在测试过程中调用该构件的系统部分。测试驱动程序将测试用例分析中标识的输人数据传递给构件并显示出测试结果。
(7)更正是对构件的一个改变。更正的目的是为了更正一个故障。请注意,更正活动也可能带来新的故障。

1.7.4测试过程
面向对象的软件测试大致可以分为以下几个阶段:
(1)构件检查,通过对源代码的手工检查,发现在单个构件中的故障。
(2)可用性测试,找出现实系统做了什么和用户所期望该系统应该做什么之间的差异。
(3)单元测试,通过使用测试桩程序和测试驱动程序来隔离单个构件的方法以发现故障,也可以通过对一个构件执行测试用例来完成这个功能。
(4)集成测试,通过集成多个构件来查找故障。
(5)确认测试,主要关注整个系统、系统的功能和非功能需求以及目标环境等。

1.构件检查
构件检查是在正式会议上通过审查源代码来发现构件中故障的过程。检查可以在单元{受4试之前执行,或者在单元测试之后执行。检查由一个开发者团队来做这件事情,这一团队包括构件的作者,主持检查过程的仲裁者和一个或多个负责发现构件中故障的评审者。该检查方法由五步组成:
(1)概述步骤。构件作者简要介绍构件的目的和使用范围以及检查的目标。
(2)准备步骤。评审者开始熟悉构件的实现。
(3)检查会议步骤。构件作者解释构件源代码,接着检查团队针对构件提出问题。仲裁者使会议在正常轨迹上运作。
(4)重做步骤。构件作者修改这一构件。
(5)后续措施步骤。仲裁者检查重做的质量并决定构件是否需要重新检查。
这些步骤中的关键一步是准备阶段和检查会议阶段。在准备阶段,评审者由于需要熟悉源代码,因此他们的注意力并没有放在故障的发现上。在召开检查会议期间,构件作者解释每个源代码语句并解释语句应该做什么。如果评审者认为有故障,他们就会提出问题。此过程中大部分时间花在讨论是否出现了故障上,但是怎样修复故障的方法并不在此阶段探索。

2.可用性测试
可用性测试着重考察用户对系统的理解。可用性测试并没有将系统和与之相对应的规格说明作比较。而是将注意力放在找出被测系统和用户期望之间的不同。由于很难定义形式化用户模型,并根据这个模型来测试,所以,可用性测试往往采用基于经验方法,即用户通过对测试系统的操作来发现问题。可用性测试也关心用户界面的细节,例如用户界面的外观和感觉,屏幕的几何布局,交互的顺序等。
典型的可用性测试有以下两类。
1)场景测试
场景从用户的角度来描述系统的行为,反映系统的期望运行方式。它是由一系列相关活动组成,它就像一个剧本,是演绎系统未来预期的使用过程。开发者标识出用户怎样才能够快速地理解应用场景,怎样精确地表示工作模型,以及怎样主动对新系统描述做出反应。场景可以看作是用户需求的内容,是完全站在用户的视角来描述用户与系统的交互过程。针对用户需求内容的测试,称之为场景测试。场景测试关注于不同场景、事务、业务流程等内容。一个场景测试用例仅测试一个场景、事务或业务流程。

2)原型测试
在软件开发过程中,原型是软件的一个早期运行的版本,它最终反映系统的部分重要特性。系统原型测试可以分为两类:垂直原型测试和水平原型测试。一个垂直原型测试过程完整地执行了贯穿系统的一个用例。垂直原型测试用于评价核心的需求,例如,系统响应时间或者在压力下用户的行为。水平原型测试了系统中单一的一个层面。例如用户界面原型测试,就是为大多数用例提供了一个界面(没有提供过多的功能或不提供任何功能)。原型测试的优点是它们提供了一个逼真的系统视图给用户,原型能够被装备而用来收集详细的数据。然而,构造原型比构造测试场景要花更多的精力。

3.单元测试
单元测试的重点是测试构建软件系统的基本单元,也就是对象和子系统。将测试的注意力放在构件上是因为:首先,单元测试减少整个测试活动的复杂性,允许关注更小的系统单元。第二,给出少量测试中被调用的构件,单元测试很容易找出并改正出现的故障。第三,在测试活动中单元测试可以并行执行。也就说,每个构件能够独立于其他构件进行测试。
从对象模型和系统分解中,选择出了单元测试的候选方案。从原则上讲,开发过程中所开发的所有对象都应当进行测试,但由于时间和预算约束,这通常是不可能做到的。被测试对象的最小集合应该是在用例中的参与对象。只有在子系统中每个对象和类都被单独测试完成以后,子系统才能够像构件一样进行测试。
正如前面已经谈到单元测试技术的种类已经非常丰富,例如模块接口测试、局部数据结构测试、路径测试、错误处理测试和边界测试等。当然,上述方法对于面向对象的软件测试也是适用的。在此针对面向对象测试特别介绍等价测试。
等价测试技术使测试用例数目最小化。可能的输入数据分割成等价类,并从每个等价类中选择测试用例。等价测试的假定是:通常认为系统中一个类的所有成员,其行为方式是类似的。要测试与等价类相关的行为,仅仅只需要测试这个类中的一个成员。等价测试包括两步:标识等价类和选择测试输入。下面的准则用于标识出等价类:覆盖。每个可能的输入属于一个等价类。不相交。任何输入都不会属于多个等价类。代表性。当一个等价类特殊成员被作为输入时,如果运行证明了一个错误状态,那么通过使用这个类的其他任意的成员作为输入,同样的错误状态也将被检测到。
对每个等价类,至少要选择两类数据:一类是典型的输入,它作为普通用例执行;另一类是无效输入,检查构件对意外情况的处理能力。在所有的等价类被标识以后,标识每个类的测试输入,以覆盖所有的等价类。如果测试输入可能无法覆盖等价类的所有成员,那么这个等价类必须被分解成更小的等价类,同时必须标识出每个新类的测试输入数据。

4.基于状态的测试
基于状态的测试技术是随着面向对象技术的发展而兴起的。大多数测试技术的重点都是针对系统的一个给定状态,选择大量的测试输入,运行构件或者系统,比较观察到的输出结果和测试预言。然而,基于状态的测试将系统的结果状态和期望状态相比较。在一个类的上下文中,基于状态的测试包括了从该类的UML状态图中导出的测试用例。对每个状态而言,从每个转换导出表示激励的集合。在采用每个激励用以确保类已经到达特定的状态之后,类的属性被测量和测试。

5.集成测试
单元测试将注意力集中于单个构件上,开发者使用等价测试、边界测试、路径测试和其他测试方法来发现构件的故障。一旦在每个构件中的故障被消除且测试用例不再揭示出任何新故障时,该构件将被集成到更大的子系统中。在这时,构件仍然可能包含有故障,这是由于单元测试期间使用的桩程序和驱动程序,仅仅是对构件的近似模拟。此外,单元测试不能揭示与构件接口有关的故障,这种故障来源于当调用这些构件接口时的无效假设。
集成测试将注意力集中于小型成组构件上,以检查单元测试期间没检查出的故障。两个或者更多构件被集成起来并加以测试,当没有新故障被揭示出来时,可增加额外的构件到这个组里来。这个过程允许增量测试更复杂的系统部分,同时保持这个加入点的潜在故障相对较小(例如,最近加入的构件通常就是触发最近所发现错误的那个构件)。
在此,将重点讨论构件根据层次进行集成的水平集成测试策略和构件根据功能进行集成的垂直集成测试策略。
1)水平集成测试策略
有好几种解决方法都可实现水平集成测试策略:自底向上测试,自顶向下测试。每种策略最初都假设:系统分解是层次的,如图11—7所示,每个构件通过“调用”关联来排序均属人某个层次。然而,这些策略很容易适应非层次系统的分解。
自底向上的测试策略首先单独测试底层的每个构件,接着将它们与上一层构件集成起来。这样一直重复,直到所有层的构件都被组合进来为止。测试驱动程序常常被用来模拟还没有集成的高层构件。注意在自底向上测试中不需要测试桩程序。
自顶向下的测试策略首先测试顶层构件,接着集成下一层的构图11—7系统分解层次件。在新的一层中的所有构件被集成在一起测试完成之后,再选择下一层构件。此外,自顶向下的测试过程是一次增加一个构件。这个过程一直重复,直到所有层被加入到测试中。测试桩程序被用来模拟还没有集成进来的、且处于较低层的构件。
注意:在自顶向下测试过程中不需要测试驱动程序。
自底向上测试的好处是更容易发现接口的故障:当开发者用测试驱动代替高层构件的时候,他们有一个低层构件如何工作的清晰模型,也具有嵌入进接口的假设条件。如果较高层的构件违反了较低层构件设置的假设条件,开发者更可能很快地发现它们。自底向上测试的缺点是它最后测试最重要的子系统,即用户接口的构件。在顶层发现的故障通常导致子系统分解的更改或者较低层子系统接E1的更改,导致先前测试无效。
自顶向下测试的优点是它是从用户接VI构件开始。从需求导出的相同测试集合,可用来增量测试复杂的子系统。自顶向下测试的缺点是开发测试桩程序是耗时的活动而且容易出错。大量的测试桩程序通常被用来测试重要的系统,特别当最底层的系统分解成许多方法实现时。
2)垂直集成测试策略
上面讨论了水平集成测试策略,这一方法的主要缺点是满足用户需求的系统只有在开发阶段的后期方可获得。垂直集成测试策略则与此相反,其所关注的是早期的集成。对于一个给定的用例,每一个构件所需要的部分,比如用户接VI、业务逻辑、中间件和存储,可以在并行地标识和开发后进行集成测试。

6.确认测试
单元测试和集成测试的重点是找出单个构件以及构件接口之间的故障。一旦构件被集成之后,确认测试就要保证整个系统服从所规定的功能需求和非功能需求。确认测试主要包含了以下内容:
(1)功能测试。功能性需求测试。
(2)性能测试。非功能性需求测试。
(3)导航测试。在目标环境中选择一组最终用户的常用性功能需求进行测试。
(4)接收测试。客户在开发环境下而不是根据验收标准(来自项目协议书),执行的可用性测试、功能测试和性能测试。
(5)安装测试。客户在目标环境中执行可用性测试、功能测试和性能测试。如果系统仅仅安装在一个有选择的小范围用户内,则该安装测试称为口测试。上述内容与1.6节中一致,故不再赘述。

文章来源:秘奥软件网,中小企业信息化领跑者!全国咨询热线:400-9908-527_www.misall.com

最新新闻: