论现代软件测试方法剖析.docx
《论现代软件测试方法剖析.docx》由会员分享,可在线阅读,更多相关《论现代软件测试方法剖析.docx(16页珍藏版)》请在冰豆网上搜索。
论现代软件测试方法剖析
第一章绪论
1.1背景
随着计算机所控制对象的复杂程度不断提高和软件功能的不断增强,软件的规模不断增大。
为了保证软件的质量和可靠性,应力求在分析、设计等各个开发阶段结束前,对软件进行严格技术评审。
但由于人类能力的局限性,审查不能发现所有的错误而且在编码阶段还会引入大量的错误。
这些错误和缺陷如果遗留到软件交付投入运行之时,终将会暴露出来。
但到那时,不仅改正这些错误的代价更高,而且往往造成很恶劣的后果。
软件测试就是在软件投入运行前,对软件需求分析、设计规格说明和编码的最终复审,是软件质量保证的关键步骤。
即软件测试是为了发现错误而执行程序的过程,或是软件测试是根据软件开发各阶段的规格说明和程序内部结构而精心设计的一批测试用例(即输入一些数据而得到其预期的结果),并利用这些测试用例去运行程序,以发现程序错误的过程。
软件测试在软件生命周期中横跨两个阶段:
通常在编写出每一个模块之后就对它做必要的测试(称为单位测试)。
编码与单元测试属于软件生存期中的同一个阶段。
在结束这个阶段之后,对软件系统还要进行个各种综合测试,这是软件生存期的另一个阶段,即测试阶段,通常由专门的测试人员承担这项工作。
大量统计资料表明,软件测试的工作量往往占软件开发工作总量的40%以上。
实际上,仅就测试而言,它的目标是发现软件中的错误,但是,发现错误并不是我们的最终目的。
软件工程的根本目标是开发出高质量的完全符合用户需要的软件。
1.2目的
基于不同的立场,存在着两种完全不同的测试目的。
从用户的角度出发,普遍希望通过软件测试暴露出软件中隐藏的错误和缺陷,以考虑是否可以接受该产品。
而从软件开发者的角度出发,则希望测试成为表明软件产品中不存在错误的过程,验证该软件已正确的实现了用户的要求,确立用户对软件质量的信心。
因为在程序中往往存在着许多意料不到的问题,可能会被疏忽,许多隐藏的错误只有在特定的环境下才可能暴露出来。
如果不把着眼点放在尽可能查找错误这样一个基础上,这些隐藏的错误和缺陷就查不出来,则会遗留到运行阶段去。
如果站在用户的角度上,就应当把测试活动的目标对准揭露程序中存在的错误。
以及在选取测试用例时尤其考虑那些易于引发程序错误的数据。
以下规则即为测试的目的:
(1)测试是为了发现程序中的错误而执行程序的过程。
(2)好的测试方案是极可能发现迄今为止尚未发现的错误的测试方案。
(3)成功的测试是发现了至今为止尚未发现错误的测试。
第二章传统软件测试方法及策略
传统软件测试方法的大致分类如下:
根据测试过程对具体实现算法细节和系统内部结构的关心情况可将软件测试分为白盒测试、灰盒测试和黑盒测试。
根据测试过程中程序的执行状态,可将软件测试分为静态测试和动态测试。
根据程序的执行方式,可将软件测试方法分为人工测试和自动化测试。
2.1白盒测试、黑盒测试和灰盒测试
2.1.1白盒测试
白盒测试为软件测试的主要方法之一,也称结构测试、逻辑驱动测试或基于程序本身的测试。
测试者需要了解待测试程序代码的内部结构、算法等信息,这是从程序设计者的角度对程序进行的测试。
这一方法是把测试对对象看做一个盒子,测试人员依据程序内部逻辑结构相关信息,设计或选择测试用例,对程序所有逻辑路径进行测试。
优点是帮助软件测试人员增大代码的覆盖率,提高代码的质量,从而发现代码中的问题。
白盒测试的测试方法有代码检查法、逻辑覆盖法、基本路径测试法、静态结构分析法等。
其中逻辑覆盖法是主要的测试方法,逻辑覆盖法包括以下几种:
(1)语句覆盖:
语句覆盖就是设计若干个测试用例,运行被测试程序,使得每一条可执行语句至少执行一次。
(2)判定覆盖(也称为分支覆盖):
设计若干个测试用例,运行被测试程序,使程序中每个判断的取真分支和取假分支至少执行一次。
(3)条件覆盖:
设计若干个测试用例,运行被测试程序,使程序中每个判断的每个条件的每个可能取值至少执行一次。
(4)判定/条件覆盖:
设计若干个测试用例,运行被测试程序,使程序中每个判断的每个条件的每个可能取值至少执行一次,并且每个可能的判断结果也至少执行一次。
(5)条件组合覆盖:
设计若干个测试用例,运行被测试程序,使程序中每个判断的所有可能的条件取值组合至少执行一次。
2.1.2黑盒测试
黑盒测试也称为功能测试,它着眼于程序的外部特征,而不考虑程序的内部逻辑结构。
测试者把待测程序看做一个黑盒子,不用关心程序的内部结构。
黑盒测试是在程序接口处进行测试,它只检查程序功能是否能正常使用,程序是否能接收输入数据产生正确的输出信息,并且保持外部信息的完整性。
黑盒测试是基于用户角度进行的测试。
具体的黑盒测试用例设计方法包括等价类划分法、边界值分析法、判定表驱动法、功能图法等。
(1)边界值分析法:
长期的测试经验告诉我们,大量的错误是发生在输入或输出范围的边界上,而不是发生在输入输出范围的内部。
因此,针对各种边界情况设计测试用例,可以测试出更多的错误。
(2)等价类划分:
等价类划分是吧所有可能的输入数据,即程序的域,划分成若干部分,然后从每个子集中选取少数具有代表性的数据作为测试用例。
该方法是一种重要的,常用的黑盒测试用例测试方法。
2.1.2灰盒测试
灰盒测试是介于黑盒测试和白盒测试之间的,即灰盒测试关注输出对于输入的正确性,同时也关注内部表现,但这种关注不像白盒那样详细,完整,只是通过一些表征性的现象、事件、标志来判断内部的运行状态,有时候运行结果是正确的,但内部其实已经错误了,这种情况非常多,如果每次都使用白盒测试来操作,效率很大大降低,因此需要采取这样的一种灰盒的方法。
灰盒测试结合了黑盒测试和白盒测试的要素。
2.2静态测试和动态测试
静态测试的基本特征是在对软件进行分析、检查和测试时不实际运行被测程序。
而是借助专用的软件测试工具评审软件文档或程序,度量程序静态复杂度,检查软件是否符合编程标准,借以发现编写的程序的不足之处,减少错误出现的概率。
可以看出,静态测试只是对代码进行扫描分析,检测它的语法规则复杂度等是否符合要求,它主要是为软件的质量保证提供依据,以提高软件的可靠性和易维护性。
动态测试,就是通过运行软件来检验软件的动态行为和运行结果的正确性。
因此,所有动态测试都必须包括两个基本要素:
一是运行被测程序,二是用以运行软件的数据。
运行软件并非动态测试的目的,通过运行来检验软件是否正确才是动态测试的真正目的。
2.3人工测试和自动化测试
自动化测试是指软件测试的自动化,软件测试就是在预设条件下运行系统或应用程序,评估运行结果,预先条件应包括正常条件和异常条件。
自动化测试是把以人为驱动的测试行为转化为机器执行的一条过程。
通常情况下,在设计了测试用例并通过评审后,由测试人员根据测试用例中的描述的规程一步步执行测试,得到实际结果与期望结果进行比较。
在此过程中,为了节省人力、时间和硬件资源,提高测试效率,便引入了自动化测试的概念。
2.4软件测试策略
通常情况下,测试过程如下:
单元测试、集成测试、系统测试和验收测试。
(1)单元测试:
单元测试又称模块测试,是针对软件软件设计中的最小单位——程序模块进行正确性检验的测试工作,其目的在于发现各模块内部可能存在的各种差错。
单元测试的内容为在单元测试时,测试者需要依据详细设计说明书和源程序清单,了解该模块的输入、输出条件以及模块的逻辑结构,主要采用白盒测试和测试用例,辅之以黑盒测试的测试用例,使之对任何合理的输入和不合理的输入,都能正确响应。
(2)集成测试:
单元测试完成之后,接下来便是集成测试。
软件集成测试主要依据概要设计文档,测试主要内容有功能性、可靠性、易用性、效率以及维护性,具体gentility软件需求和设计的要求而定。
集成测试验证各软件模块集成后的模块是否能达到概要设计说明中各模块的设计目标。
(3)系统测试:
系统测试属于黑盒测试范围,是在系统集成测试修改完bug后进行的测试。
从软件工程和测试的分类来看,集成测试在系统测试之前就必须要进行完毕,只有集成测试完成了,才能保证相应的系统测试进行。
系统测试是针对整个产品的全面测试,既包含各模块的验证性测试和功能合理性测试,又包括对整个产品的可靠性、健壮性、安全性、UI合理性及各种性能参数的测试。
(4)验收测试:
验收测试属于黑盒测试范围,是对系统测试修改后的复审,这步和集成测试有些类似,首先确认系统测试中bug已经按要求修改完成,然后检测一下功能是否符合用户的需求、文档是否完整、是否还有遗留的没有测出的bug。
第三章现代软件测试方法
3.1面向对象的软件测试
面向对象技术是一种全新的软件开发技术,正逐渐代替被广泛使用的面向过程开发方法,被看成是解决软件危机的新兴技术。
面向对象技术产生更好的系统结构,更规范的编程风格,极大的优化了数据使用的安全性,提高了程序代码的重用,一些人就此认为随着00A和OOD的成熟,更多的设计模式复用将减轻OO系统的繁重测试量。
应该看到,尽管面向对象技术的基本思想保证了软件应该有更高的质量,但实际情况却并非如此,因为无论采用什么样的编程技术,编程人员的错误都是不可避免的,而且由于面向对象技术开发的软件代码重用率高,更需要严格测试,避免错误的繁衍。
为了获得面向对象系统的高可靠性,可能将需要更多而不是更少的测试。
因此,软件测试并没有因面向对象技术的兴起而丧失掉它的重要性。
面向对象软件的测试从对OO分析模型的评审开始。
一旦代码生成,OO测试开始“小规模”类测试。
一系列测试被设计以检查类操作并检查当某类和其他类协作时是否有错误发生。
类被集成以形成子系统,基于线程的、基于使用的和集群测试结合基于故障的方法,被用于完全地测试协作类。
最后,use—case被用于发现在软件确认级的错误。
(1)面向对象的单元测试
面向对象软件的单元概念发生了变化。
封装驱动了类和对象的定义,这意味着每个类和类的实例包装了属性和操纵这些数据的操作。
而不是个体的模块。
最小的可测试单位是封装的类或对象,类包含一组不同的操作,并且某特殊操作可能作为一组不同类的一部分存在,因此,单元测试的意义发生了较大变化。
我们不再孤立地测试单个操作,而是将操作作为类的一部分。
对OO软件的类测试等价于传统软件的单元测试。
和传统软件的单元测试不一样,它往往关注模块的算法细节和模块接口间流动的数据,OO软件的类测试是由封装在类中的操作和类的状态行为所驱动的。
(2)面向对象软件的集成测试
因为面向对象软件没有层次的控制结构,传统的自顶向下和自底向上集成策略就没有意义,此外,一次集成一个操作到类中(传统的增量集成方法)经常是不可能的,这是由于“构成类的成分的直接和间接的交互”。
对00软件的集成测试有两种不同策略,第一种称为基于线程的测试,集成对回应系统的一个输入或事件所需的一组类,每个线程被集成并分别测试,应用回归测试以保证没有产生副作用。
第二种称为基于使用的测试,通过测试那些几乎不使用服务器类的类而开始构造系统,在独立类测试完成后,下一层的使用独立类的类成为依赖类,被测试。
这个依赖类层次的测试序列一直持续到构造完整个系统。
(3)面向对象软件的系统测试
在系统这一层次,类连接的细节消失了。
传统的黑盒测试方法可被用于驱动有效性测试。
此外,测试用例可以从对象这一行为模型中导出。
3.2基于构件的软件测试
随着软件开发机构对开发成本、周期要求的提高,产生了软件构件化。
软件构件技术的提出解决了面向对象技术无法使大量结构相似的应用程序结构得到重用的矛盾。
继面向对象的设计方法之后,基于构建的软件设计方法正在逐渐成为新的趋势。
由于构件的特点,构件的测试问题应该从构件的开发者与构件的使用者两个角度来看,其原因是:
一是他们使用的环境(包括编程语言、操作系统、硬件平台)可能不同:
二是拥有的资源不同,构件开发者拥有构件源代码,构件使用者可能只有构件的可执行代码:
三是测试目的不同,构件的开发者需要测试构件的所有功能,构件的使用者只关心与他有关的构件功能。
3.2.1国内外研究现状
国外在构件软件的测试技术领域已有一些研究[1],各种方法的比较,如表1所示。
而国内在基于构件的软件开发方面已开展了一些工作,如北京航空航天大学的刘超等提出了一种白盒测试工具的设计方法,就是基于构件的思想。
在软件测试工具的开发方面,北京航空航天大学的CHENXuesong等提供了构造运行剖面和产生测试数据的计算机辅助工具,暨南大学的CHENHuoyan提供了基于代码插装的类簇级测试工具[2]。
但是对基于构件的软件测试技术研究与测试工具开发方面的研究还比较少。
表1国外软件构件的测试技术表
编号
测试技术
系统测试还是单元测试
有无自动化工具支持
1
Certificationofcomponent
都是
有
2
Componenttestbench(CTB)
单元测试
有
3
UMLIntegrationtest
系统测试
无
4
Componentinteractiontest(CIT)
都是
有
5
TDS
都是
有
3.2.2基本内容
构件软件测试的基本内容包括以下几点:
(1)单元测试:
软件系统中每一个单个的构件都经过测试;
(2)集成测试:
对已测试过的构件集成的子系统作为一个实体进行测试;
(3)系统测试:
对已测试过的子系统形成的系统作为一个实体进行测试;
(4)回归测试:
对软件系统所做的任何修改以后都必须进行相应的重新测试。
3.2.3构件测试中涉及到的问题
构件测试包括以下问题:
(1)测试充分性判据的可扩展性。
由于复杂性问题和组合爆炸问题,对小规模程序适用的判据对大规模程序不一定适用。
(2)测试数据的产生。
由于同样的原因,难以产生合适的测试输入,使得对低层次元素(如分支、定义使用对,需求功能可看作是高层元素)难以达到较
高的覆盖率。
(3)如何配置构件的测试环境。
对单个构件进行测试的环境,与构件在实际系统中运行的环境可能不同。
所以在测试构件时应该考虑模拟真实环境,如构件的竞争和死锁和多线程等。
但是由于构件的复用,难以完全模拟构件使用的所有真实环境。
(4)构造测试驱动器和打桩技术。
传统的技术是面向特定的工程,但是构件的多样性和其功能的专用化使得传统的技术达不到应有的效力。
(5)构件测试的可重用性。
对构件的测试应该是可重用的。
3.2.4构件使用者面临的测试问题
(1)测试充分性判据的可扩展性问题依然存在。
(2)构件的测试顺序。
如果软件采用分层结构,可以先测试底层构件,因为不需要其他构件提供服务;然后再测试高层构件,所调用到的其他构件都是经过测试的。
如果不是分层结构,就可能难以确定测试的顺序。
(3)冗余测试问题。
通常先对构件进行单独测试,然后使用相同的充分性判据进行集成测试,这就导致有些测试是重复的。
(4)源代码是否可用。
源代码可用与否导致不同的系统测试方法。
(5)编程语言、操作系统平台、硬件结构的混杂性。
系统使用的构件可能是用不同语言编写的,运行在不同的平台上,这就要求测试方法和工具与平台和语言无关。
(6)测试分布式软件时的监控问题。
分布式系统比集中式系统复杂得多,其监控和数据收集存储机制也更为复杂。
(7)事件重构。
分布式系统中经常有并发处理和异步通讯,对整个运行环境难以完全掌控。
这就导致程序的执行情况难以重现,因此只测试构件不足以说明系统的可靠性。
3.3嵌入式软件测试
随着经济的发展和科技的进步,信息技术的发展使人类进入数字时代,而伴随着计算机技术发展起来的嵌入式技术得到了巨大的发展,改变了人们的日常生活。
随着对嵌入式产品对各方面的要求越来越高,对嵌入式产品的性能有着决定性影响的嵌入式软件的测试显得尤为重要。
嵌入式软件测试的目的是保证软件满足需求规格说明,与非嵌入式软件的测试目的是一样的。
系统失效是系统没有满足—个或多个正式需求规范中所要求的需求项,嵌入式软件有其特殊的失效判定准则。
而且嵌入式软件对可靠性的要求比较高。
安全性的缺陷往往会导致灾难性的后果,即使是非安全性系统,由于大批量生产也会导致严重的经济损失。
这就要求对嵌入式系统,包括嵌入式软件、嵌入式硬件进行严格的测试、确认和验证。
一般来说,软件测试有7个基本阶段,即单元测试、集成测试、功能测试、回归测试、系统测试、验收测试、安装测试。
嵌入式软件测试在4个阶段上进行,即模块测试、集成测试、系统测试、硬件/软件集成测试。
前3个阶段适用于任何软件的测试,硬件/软件集成测试阶段是嵌入式软件所特有的,目的是验证嵌入式软件与其所控制的硬件设备能否正确地交互。
3.2.1嵌入式软件测试环境
嵌入式软件测试的测试环境主要有两种:
(1)目标环境测试:
基于目标的测试测试全面有效,但是消耗较多的经费和时间。
(2)宿主环境测试:
基于宿主的测试代价较小,但是有些对环境要求高的功能和性能宿主机无法模拟,测试无法实现。
目前的趋势是把更多的测试转移到宿主环境中进行,把宿主环境测试无法实现的复杂和独特功能放在目标环境测试。
我们的工作重点是基于宿主环境的测试,基于目标环境的测试作为补充。
在两个环境中可以出现不同的软件缺陷,重要的是目标环境和宿主环境的测试内容有所选择。
在宿主环境中,可以进行逻辑或界面的测试、以及与硬件无关的测试。
在模拟或宿主环境中的测试消耗时间通常相对较少,用调试工具可以更快地完成调试和测试任务。
而与定时问题有关的白盒测试、中断测试、硬件接口测试只能在目标环境中进行。
在软件测试周期中,基于目标的测试是在较晚的“硬件/软件集成测试”阶段开始的,如果不更早地在模拟环境中进行白盒测试,而是等到“硬件/软件集成测试”阶段进行全部的白盒测试,将耗费更多的财力和人力。
3.2.2嵌入式软件测试内容
嵌入式软件测试的内容主要为:
软件代码测试、编程规范标准符合性测试、代码编码规范符合性测试、开发维护文档规范符合性测试、用户文档测试。
而软件测试服务范围包括:
系统级测试、应用测试、中间件测试、BSP及驱动程序测试、嵌入式硬件设计测试。
若按照嵌入式软件有无操作系统将嵌入式系统分为两大类:
无操作系统的嵌入式软件、有操作系统的嵌入式软件。
3.4代理测试
代理测试可以认为是比黑盒更“黑”的测试,即要求获得测试结果的人员或组织根本不直接对软件进行测试,而是将其提交给专门的测试机构进行测试,然后将结果返回。
采用独立测试方式,无论在技术上还是管理上,对提高软件测试的有效性都具有重要意义[3]。
3.5净室测试
净室过程组合了形式化程序验证和统计过程控制。
在这种方法中,首先用正确性数学证明预防缺陷发生,然后用MTBF度量软件质量。
通过在第一次正确地书写代码增量并在测试前验证它们的正确性来避免对成本很高的错误消除过程的依赖。
净室方法还强调统计质量控制技术,包括基于客户对软件的预期的使用的测试即统计性测试[4]。
第四章移动医疗网的测试报告
4.1概述
本章拟采用面向对象的软件测试方法对移动医疗网进行测试。
具体的测试步骤可分为4个层次方法测试、类测试、类簇测试和系统测试。
(1)方法测试:
指对类中的各个方法进行单独的测试,但实际上类中的方法是不能脱离类而单独存在的,因此我们没有将方法测试作为一个独立的层次来考虑,而主张将其看作类测试的一部分。
而对各个方法进行相对独立的测试还是可行的,对独立方法的测试类似于对独立过程的测试类测试。
(2)类测试:
与传统软件相比面向对象程序的子过程(方法)的结构较简单,而方法间的耦合程度大大提高,交互过程也变得复杂,因此面向对象程序测试的重心就由对各独立过程进行的单元测试转移到了过程间的集成测试上,即测试的重点是类及类以上的各个层次。
并且由于类是面向对象组成和运行的基本单元,因此对它的测试也就显得更加举足轻重。
在对传统软件进行测试时,我们注重的是程序的控制流或数据流,但对类进行测试时则必须考虑类的对象所具有的状态,并且着重考察一个对象接收到一个消息序列之后,是否达到了一个正确的状态。
因此类测试的重点是类内方法间的交互和其对象的各个状态。
(3)类簇测试,即由若干个类所组成的子系统测试。
这些类之间存在着诸如派生、聚集和联系等关系,对类簇的测试应着重于考察上述关系的正确实现。
如果将类簇看作一个整体,其行为特点与类有许多相似之处,因此类簇的测试方法一般与对类的测试方法相似。
(4)系统测试。
系统测试是检验整个软件系统是否符合要求。
由于系统测试不考虑内部结构和中间结果,因此面向对象的系统测试与传统软件的系统测试区别并不大,可参考传统的系统测试方法。
以下为移动医疗网的测试报告,目的在于总结测试阶段的测试情况以及分析测试结果,描述系统是否符合用户需求,是否已达到用户预期的功能目标,并对测试质量进行分析。
移动医疗网的主要功能包括:
用户登录、注册信息、社区论坛、用户个人中心、搜索。
4.2具体操作
4.2.1测试类型
具体实现是基于移动移动网使用面向对象的测试方法,下面将通过具体实例,简要的说明面向对象的测试方法。
在方法测试中,该平台的user(用户)类有下列操作:
login(登录)、register(注册),find(搜索),add(增加信息),delete(删除信息),update(更新信息)。
上述的每个方法都可以应用于user类实例,但是该平台中在对某些操作的进行施加了一些限制,例如必须在其他操作之前进行登录。
执行上述这些随机测试用例,随机产生测试结果。
接着便是类测试,在类测试的过程中,发现该类有代码冗余的问题,例如add()和register()中存在着任务重复的问题。
该问题造成了代码重复,同时也造成了系统内存的浪费。
再类测试中我们还做了database()类的测试,包括对数据库的连接,关闭等。
均通过。
由于本系统中的类不存在耦合,继承等关系,因此没有进行面向对象软件测试中的第三步。
最后一步便是系统测试,该步与面向过程的系统测试方法想类似。
具体的测试类型、测试内容、测试目的如下表2所示:
表2测试类型表
测试类型
测试内容
测试目的
所用的测试工具和方法
功能测试
1、客户端:
用户登录、注册信息、社区论坛、用户个人中心、搜索
2、后台管理:
信息审核、配置文件管理、社区管理、注册用户管理、系统管理
核实所有功能均已正常实现,即可按用户的需求使用系统
1、业务流程检验:
各个业务流程能够满足用户需求,用户使用不会产生疑问
2、数据准确:
各数据输入输出时系统计算准确
采用黑盒测试,使用边界值测试、等价类划分等测试方法,进行手工测试
用户界面测试
1、导航、链接、Cookie、页面结构包括菜单、背景、颜色、字体、按钮、Title、提示信息的一致性等
2、友好性、易用性、合理性、一致性、正确性
核实网站风格符合可接受标准,能够保证用户界面友好性、易操作性,符合用户操作习惯
手工测试
安全性和访问控制测试
1、密码:
登录、用户、专家、管理员
2、权限限制
3、通过修改URL非法访问
4、登录超时限制
1、应用程序级别的安全性:
核实用户只能操作其所拥有权限能操作的功能
2、系统级别的安全性:
核实只能具备系统访问权限的用户才能访问系统
黑盒测试、
手工测试
兼容性测试
1、用不同版本的不同浏览器:
IE8.0、火狐、360浏览器,分辨率:
1024×768、800×600,操作系统:
WIN8、WIN7
2、不同操作系统、浏览器、分辨率等组合测试
核实系统在不同的软件和硬件配置中运行稳定
黑盒测试、
手工测试
4.2.2测试用例执行结果
设计好测试用例之后,具体的测试结果如下表3所示:
表3测试用例执行结果表
测试用例标识符
测试用例名称
状态
测试结果
备注
业务测试
001
用户登录流程
已执行
测试通过
002
用户注册流程
已执行
测试通过
003
用户提问,回答流程
已执行
测试通过