前进中的可信计算(Ⅴ):软件测试

发表于:2007-9-14 18:29

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:网络转载

分享:

        软件可靠性牵涉到软件生产的全过程,但最终还是落实到软件产品上。而保证软件可靠性的关键步骤是软件测试

        软件测试是为了发现故障而执行程序的过程。其目的是以尽可能少的时间和人力发现并改正软件中潜在的各种故障及缺陷。因此,软件测试与软件可靠性紧密相关。软件中隐藏的故障数目,直接决定软件的可靠性。所以,在软件投入运行之前必须进行软件测试,以尽可能多地发现软件中的故障,提高软件可靠性。而在软件运行过程中,则需要软件维修测试。

        随着人们对软件测试重要性认识的加深以及软件系统的日益复杂,软件测试在整个软件开发周期中所占的比例日益增大。目前,许多软件开发机构已将研制力量的40%以上花费在软件测试上。特殊情况下,对于要求高可靠性的软件,例如飞行控制、核反应堆监控软件等,其软件测试费用甚至高达软件开发其它阶段所用费用总和的3-5倍。

1.   软件测试工程

        软件测试的实质是根据软件开发各阶段的规格说明和程序的内部结构精心选取一批测试数据,形成测试用例,并用这些测试用例去驱动被测程序,观察程序的执行结果,验证所得结果与预期结果是否一致,然后做相应的调整。所以,软件测试本身是一个工程。软件测试的团队必须不同于该软件的设计团队,它必须独立地确定软件测试规范、生成测试数据、进行测试结果分析、写出测试报告。这一过程可能要反复进行多次,以达到预定的可靠性。在此过程中,测试数据生成是软件测试的核心与关键。不同测试数据对发现软件故障的能力差别很大。某些测试数据能够有效地发现故障,而其他一些测试数据也可能完全是徒劳。为了节约时间和资源,提高测试效率,必须从大量的输入数据中精心挑选出少数有代表性的测试数据,使得采用这些测试数据能够达到最佳的测试效果,高效地把隐藏的故障揭露出来。为此,探讨如何生成高质高效的测试数据,至关重要。而软件测试生成与被测软件的性质、功能和可靠性要求紧密相关。

2.基于程序结构的测试生成

        基于规范的功能测试又称黑盒测试,是以检查程序功能来检测程序是否按照规格说明书的规定正确地运行,它以规范说明为依据,选择和设计测试用例。基于程序的结构测试又称白盒测试,则根据程序的内部结构设计测试用例,检测程序在各种不同的情况下是否都按预定的要求正确地运行。基于规范的测试数据生成和基于程序的测试数据生成是两类常用的软件测试数据生成方法。

        结构测试要求对被测程序的结构特性作到一定程度的覆盖。覆盖准则一般有以下几种:

①    语句覆盖

        希望用测试数据运行被测程序时,被测程序的每一个语句都能被执行。至少说明每一个语句都是可达的,在该测试条件下,程序是正确的。当然我们并不能保证在其他条件下,程序执行该语句时是否也能正确。

②    分支覆盖

        在If … then … else …语句中,条件语句测试执行一次是不够的。因为必须让条件为真和为假,至少执行两次。而在Case语句中必须运行所有的情况,而且,还要运行不属于所列情况的default情况。所以,对这些分支语句,必须覆盖所有可能的分支。分支覆盖率就是考察测试数据覆盖了百分之多少的分支。

③路径覆盖

        由于程序中有分支、循环、递归、调用、跳变等语句,一个程序可以用一个控制流或数据流图来表示。程序的每一次运行都是沿着某一条路径走的。程序在运行这些测试数据时,沿着许多路径都运行过。如果能沿着所有路径都运行一遍,当然很好。如果能做到完全的路径覆盖,就必然达到100%的分支覆盖和语句覆盖。但是,对于较大的程序,基本上不可能沿着所有路径都运行一遍,因为路径数太多了。运行过的路径数对所有路径数的百分比就是路径覆盖率。

        测试数据生成的过程就是在输入域中,寻找满足测试准则(如语句覆盖、分支覆盖或路径覆盖)的输入数据的过程。

        关于结构测试,有三种测试数据生成方法:随机测试数据生成方法、面向目标的测试数据生成方法以及面向路径的测试数据生成方法。

        对于给定的语句(分支或路径),随机测试数据生成方法是在输入域内随机选取测试数据,使得给定语句被执行。

        面向目标的测试数据生成方法,依据程序控制流信息,将程序中所有的分支分成两类:一类是影响目标结点的分支,另一类是不影响目标结点的分支。测试数据生成时,根据影响目标结点的那些分支,生成相应的测试数据,使得给定语句被执行。为了能按照预定的分支,走向给定语句,数据依赖分析是必要的。分析数据依赖关系,识别影响给定语句执行的那些语句,即先于给定结点执行的结点序列,再考虑影响目标结点的那些分支,可以提高测试数据生成效率。面向目标的测试数据生成方法,与路径选择无关,虽然可以达到语句覆盖、分支覆盖,但在结构测试覆盖准则中,路径覆盖率是较低的,只有当程序中每一条路径都被测试了,才能说程序得到了全面的检验。

        面向路径的测试数据生成方法,首先确定一条经过给定语句的程序路径,这条路径可以自动生成,也可以人为指定。然后在输入域中寻找输入数据,使得在此输入之下,程序沿该路径运行,从而使得给定语句被执行。面向路径的测试数据生成又分为符号执行和实际程序执行两类。符号执行允许程序输入常量、符号值、符号表达式等,以符号计算代替实际执行的数值计算,产生一个符号输入值的代数表达式,即路径约束,它是选定路径的谓词系统。实际上是对输入数据的限制要求,由多个不等式(等式)组成。通过求解不等式,求取满足路径上各限制谓词的测试数据。若系统无解,则相应的路径为不可行路径。与逻辑电路测试类似,软件测试也可以基于故障来产生。用代数约束来描述检测特定类型故障的测试数据。符号执行能够判定路径的可行性,一次符号测试的结果代表了一类普通测试的运行结果,因此测试成本较低。但在遇到循环、过程调用、动态数据结构、数组和指针处理时,符号执行实现困难。基于程序实际执行的测试数据生成方法可以对选定路径上的分支谓词,写出一个逻辑表达式,再进行布尔函数极小化,以确定输入数据,使程序执行沿选定路径进行。也可以利用迭代逼近法,求取满足选定路径上所有谓词的输入值。每次迭代中,执行与选定路径谓词有关的语句,得到一个线性约束集,求解该线性约束集,获得一个输入增量,进而得到下次迭代的输入值,最终产生选定路径的测试数据。也可以用约束求解的方法生成测试数据,将被测程序转化成一个约束系统,然后寻找经过给定语句的路径,生成相应的测试数据。基于程序实际执行的测试数据生成方法,在程序执行的每一步,数组下标、指针值都是确定的。因此,对数组和指针的处理方便,但其测试数据生成与路径选择有关,而判定所选路径是否为可行路径是一件非常困难的事情。

        随机测试数据生成、面向目标的测试数据生成和面向路径的测试数据生成方法大多只利用控制流信息生成测试数据。而利用数据流信息生成测试则是另一类测试生成方法。该方法将数据流信息应用到路径选择中,并定义了相应的测试覆盖准则。例如,所有定义引用路径覆盖准则是指在一个变量被定义之后,所有引用该变量的语句都必须被覆盖。而所有定义覆盖准则则要求所有定义变量的语句都必须被覆盖。所有计算引用覆盖准则要求所有计算出来的变量被引用的通路都必须被覆盖。数据流测试已经开发了一些软件测试工具,例如ATAC,能够评估测试集的覆盖率,识别未被覆盖的程序范围等,有利于指导选择测试用例,提高测试覆盖率。但是,无论哪一种结构测试,即使其覆盖率达到百分之百,也不能保证把所有隐藏的程序缺陷都揭露出来。

3.面向对象软件的测试

        面向对象的方法(Object-oriented method, OO)是软件工程方法的一次飞跃。对象是一个具有一组状态的实体,并封装了附加于这些状态的操作。状态描述了对象的属性或特征,操作描述了对象改变其状态的方法以及该对象为其他对象所提供的服务。面向对象方法认为,人类生活在一个由对象组成的世界中。对象可以被归类、描述、组织、组合、创建和操纵。面向对象方法是一种模型化世界的抽象方法,结构上具有良好的高内聚低耦合特性。采用面向对象技术设计和开发的软件系统更易于维护,在对系统进行修改时,能够产生较少的副作用。同时,面向对象技术提出了类、继承、接口等概念,从而为对象的复用提供了良好的支持机制。因而采用面向对象技术对软件产品进行设计与开发,能够有效地提高软件组织的开发效率。

        随着面向对象分析和面向对象设计技术的日渐成熟,面向对象的软件开发技术得到了软件界的普遍认可。但是,由于面向对象的程序设计语言提供了数据抽象、继承、多态和动态绑定等机制,传统的软件测试方法以及测试工具已不能为面向对象的软件提供良好的支持。

        面向对象的程序中,对象是封装了描述其属性的数据及可以施加在这些数据上的操作的封装体。属性表示对象的状态,操作表示对象的行为,消息描述了对象执行操作的规格说明。对象之间通过发送消息启动相应的操作,通过修改对象的状态,实现系统状态间的相互转换。类是对具有相同属性和行为的一组相似对象的描述,它描述了该类对象所具有的共同特征。面向对象软件的测试与传统的软件测试有所不同。从面向对象单元测试开始,要考虑类间的继承测试。可以根据类间继承关系的层次特性对类进行增量测试,即通过复用和增量更新父类的测试信息去指导子类的测试。有人根据类是抽象数据类型的实现这一原理,引入了一种和面向对象语言语法相似的代数规范描述语言LOBAS,作为类的测试模型。通过分析软件的需求和功能规范来选择和产生测试数据,重点测试一个作用于被测类对象的消息序列能否使该对象处于正确的状态。也可以采用黑盒测试和白盒测试相结合的方法,用黑盒测试法选取测试用例,用白盒测试来检测程序执行一个测试用例产生的两个对象是否观测等价(即处于相同的抽象状态),并补充一些测试用例,对类进行测试。

        对传统软件,测试人员普遍认为可以分为四个级别的测试:单元测试、集成测试、确认测试和系统测试。面向对象的程序测试应当分为几个级别,目前尚未达成共识。一种意见认为,从面向对象程序的结构出发,面向对象的程序测试应当分为四个级别:

1). 行为级:测试类中定义的每个操作;

2). 类级:测试封装在一个类中的操作和数据之间的相互作用;

3). 簇级:测试一组协同工作的类之间的相互作用;

4). 系统级:考察由所有类和主程序构成的整个系统。

        而另一种意见则认为面向对象的程序执行实际上是执行一个由外部事件驱动的操作序列。根据这一特征,应将面向对象的测试分为五个层次:

1). 行为测试;

2). 消息路径测试;

3). 系统基本功能测试;

4). 线程测试;

5). 线程间相互作用测试。

        继承是指子类自动共享父类中定义的数据和操作的机制,多态是指当同一个消息被不同的对象接受时,可以导致完全不同的行为。继承与多态机制,是面向对象程序实现重用的主要手段,同时也给面向对象软件的测试提出了一些新的问题。目前关于面向对象软件测试的研究,大多集中在类和对象状态的测试方面。虽有文献提及继承及动态绑定对软件测试的影响,但现有的面向对象软件测试方法大都忽略了动态绑定的作用和影响,而且尚无普遍接受的面向对象软件测试的充分性准则。对这些问题的深入研究将会对软件测试的理论与实践起到积极的指导作用。

4.软件测试工具

        为了提高软件测试效率,加快软件开发过程,许多公司和大学、科研机构开发了软件测试工具。我国在软件测试工具研发方面也做了大量工作。它们大致可分为静态分析工具、测试数据生成工具、测试评估工具以及将多种测试工具融为一体的集成化测试系统等。

· 静态分析工具

        静态分析工具是在不执行程序的情况下,分析软件的特性。静态分析主要集中在需求文档、设计文档以及程序结构上,可以进行类型分析、接口分析、输入输出规格说明分析等。

· 测试数据生成工具

        测试数据生成工具可以为被测程序自动生成测试数据,减轻人们在生成大量测试数据时付出的劳动,同时还可避免测试人员对一部分测试数据的偏见。

· 测试评估工具

        测试评估工具用来评估程序结构元素被覆盖的程度,从而确定测试运行的充分性。这是使用测试数据生成工具生成测试数据之后必须使用的工具。

· 集成化测试系统

        集成化测试系统将多种测试工具融为一体,是一种功能较强的测试工具。

        一般地说,针对一类特定软件的测试工具,可以是相当有效的。而要想开发对所有软件系统都有效的软件测试工具,几乎是不可能的。并且,经验表明,走查,即由测试工程师认真阅读源程序以发现错误,仍不失为一种靠得住的测试方法,虽然这不属于自动测试方法。

5.程序切片技术

        对于大型的复杂软件系统的测试,应该提到程序切片技术。它是一种分析和理解程序的技术,广泛应用于程序调试、测试、逆向工程及软件维护中。它以切片标准为准则,从被测程序中抽取满足切片标准要求的有关语句,忽略许多与此无关的语句,有利于故障原因的定位分析。

        程序切片是一个可执行的程序部分,由可能影响程序某个兴趣点处变量值的所有语句和谓词组成。

        程序切片分为静态切片和动态切片。

        静态切片考虑了程序所有可能的执行路径。通过分析源程序代码,获得有关信息,可以计算程序的静态切片。对于程序的某个变量而言,静态切片计算出的该变量值与源程序计算出的该变量值在任何输入下都是相同的。

        动态切片只考虑某个具体输入下程序的执行路径,由路径上影响或间接影响程序某个兴趣点处变量值的所有语句和谓词组成。根据实际输入执行产生的精确数据流信息,即在特定执行过程中产生的数据依赖,计算程序的动态切片。

《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号