第7章软件测试
软件验证是通过检查和提供客观证据表明软件已经满足规定的需求,是确保软件质量和降低软件成本的重要手段,进行软件验证的方式有两种测试和证明,
软件测试又可以分为两类,静态测试和动态测试,静态测试又称评审,是对软件进行的一种分析和检查活动,动态测试是通过运行软件来检验其动态行为和运行结果的正确性,
软件证明,软件证明是一种通过形式化的数学方法来确保软件正确性的活动,
7.0序言,
软件测试是在软件投入运行之前,对软件需求分析,设计规格说明和编码的复审,是为了发现错误,通过检查可提供客观证据表明软件已经满足规定的需求,软件测试是确保软件质量和降低软件成本的重要手段,涉及了整个的软件生存周期,
软件错误往往有很多来源,比如开发者和用户之间的交流不畅,开发者和管理人员的经验素质有缺陷,软件的需求异变不稳定,软件的系统复杂,规模大,
软件测试的复杂性与经济性,软件测试情况数量巨大,复杂度往往很高,不能够通过穷举来确定,所以为了降低测试的成本,我们选择测试用例的同时,应该遵循经济性的原则,测试的主要影响因素有,系统的类型,潜在的用户数量,信息的价值,开发机构,测试的时机,
7.1软件测试基础,
软件测试并不等于程序测试,软件测试的对象是软件生存周期各阶段的文档和代码,
软件测试就是试图以最少的代价发现软件分析设计和编码中存在的各种不同类型的错误,从而提高软件质量,降低软件成本,
- 软件测试原则,
- 测试应尽早的和不断的进行,
- 应较早确定测试计划,严格执行测试计划,
- 注意错误的群集现象和应用pareto原则,
- 测试规模应从小到大,
- 测试应一般由独立的第三方来完成,
- 应保证测试用例的完整性和有效性,
- 应保存所有的测试用例和出错统计直到软件不用为止,
- 软件测试工具,
软件测试工具是一种测试软件,开发人员介绍它可以提高测试软件的效率,按工作方式可以分为静态测试软件和动态测试软件,按功能分可以分为,测试计划工具,测试设计与开发工具,测试执行工具,测试评价工具,测试管理工具,其他辅助工具,
静态分析测试软件,通过扫描被测程序的正文,对其数据流和控制流进行分析,
动态分析测试软件,通过对被测程序有控制的运行,自如的监视记录和统计被测程序的运行情况,
测试数据自动生成程序,用来为测试程序自动产生测试输入数据,
文件比较程序,用来自动检验测试成果,
- 测试组织,
一般来讲,独立测试前,软件开发者应该对单个模块进行测试,不仅如此,软件开发者也应该进行集成测试,在系统形成之后,测试组织才开始介入,
- 测试与调试,
测试是查找错误症状的过程,调试则是查找错误症状原因并改正错误的过程,
- 动态测试步骤,
动态测试一般分为以下4个步骤,
单元测试 单元测试对应的是软件开发过程的详细设计说明书,
集成测试 集成测试对应的是软件开发过程中的概要设计说明书,
确认测试 确认测试对应的是软件开发过程中的需求规格说明书,
系统测试 系统测试对应的是软件开发过程中的用户要求,
7.2代码复审,
代码复审一般在程序通过编译及静态分析工具检查之后,在动态测试之前进行,
代码复审的主要方法有,代码会审,走查,办公桌检查,
- 代码复审的内容,
对源程序代码进行的复审主要着重于检查代码实现是否完备正确的,在复审过程中,可以对照有关条例或错误检验表,查找程序在结构,功能,编码标准和风格等方面的错误或提出质疑,
- 代码会审,
会审小组一般由4人左右组成,会前小组负责人将带评审的材料及有关附件发放给与会者,会上程序作者逐句朗读并讲解程序代码,其他人则集中精力检查错误表,会后应把查出的问题清单交给程序作者处理,作者处理完后再交回组长,
- 走查,
会前发放有关材料,给与会者进行熟悉,并至少指定一人设计测试用例,会上,与会者扮演计算机角色,人工执行被测程序通过将测试用例输入被测程序,对程序的逻辑和功能提出疑问,已发现程序中存在的问题,会后,处理程序与代码会审相同,
- 办公桌检查,
办公桌检查可以看成是由一个人进行的代码复审,程序作者在程序通过编译之后进行单元测试之前,对源代码进行分析检验并补充有关文档,
7.3白盒测试,
白盒测试是一种以程序的内部逻辑结构为依据设计测试用例的方法,因而又称结构测试或玻璃盒测试,白盒测试主要有两种方法,一种称为逻辑覆盖法,另一种称为路径覆盖法,除此外对循环的测试可采用循环覆盖法,
- 逻辑覆盖法,
逻辑覆盖法分为以下几个覆盖等级,
语句覆盖,测试用例能使测试程序中的每条语句都执行一次,
判定覆盖,测试用力能使被测程序中的每个判定至少取得一次,真和一次假,
条件覆盖,测试用例能使被测程序中的每个判定的每个条件至少取得一次,真和一次假,如果判定中只有一个条件,则条件覆盖等于判定覆盖,
判定条件覆盖,测试用例既满足判定覆盖也满足条件覆盖,
条件组合覆盖,测试用例使每个判定中所有可能的条件取值组合,至少执行一次,
- 基本路径覆盖法,
逻辑覆盖法并没有检测程序的所有执行路径,所以我们提出了基本路径覆盖法,基本路径测试法是在程序图的基础上,通过分析环形复杂性导出基本路径及然后测试用例,使基本路径集中的每条路径至少经过一次,
基本路径覆盖法的步骤,
1、以详细设计结果或源程序代码为基础导出程序图,程序图中的每个圆圈代表一个条件或语句,每个箭头代表一条控制流,
2、计算程序图的环形复杂度,计算程序流程图中的判定数量,然后加1,也可采用图形矩阵方法,
3、确定基本路径集合,环形复杂度为5,基本路径有5条,
4、生成测试用例,基本路径集合中的每条路径至少经过一次,
- 循环覆盖法,
逻辑覆盖法和基本路径覆盖法对于循环只进行了循环一次的测试,对于结构化程序而言,循环主要有三种,简单循环,嵌套循环,串接循环,
对于简单循环,如果循环n次,测试用例可以循环,0次,一次,两次,小于n次,分别循环n-1n和n加一次,
对于嵌套循环,可以从最内层循环开始,其他循环设置为最小次数循环,
与串接循环,如果串接循环的循环彼此独立,则可以采用简单循环的测试策略,如果循环不独立,应使用嵌套循环的循环测试策略,
7.4黑盒测试,
黑盒测试又称功能测试,数据驱动测试,他把测试对象看成是一个黑盒子,不考虑程序内部的逻辑结构,
通常白盒测试用于程序测试的早期,黑盒测试用于程序测试的后期,
黑河测试通常用来发现以下类型的错误,功能错误,接口错误,数据错误,性能错误,初始化或终止错误,
黑盒测试的设计方法,等价分类法,边界值分析法,猜错法,因果图法,
- 等价分类法,
等价分类法将所有可能的输入数据划分成为若干个等价类,然后从每个类中挑选一个代表形成测试用例,我们假定等价类中所有数据对于暴露程序错误的效果是等效的,
下述等价分类只能有利于等价类的划分,
- 如果输入条件规定了一个取值的范围或值的个数,可以定义一个有效等价类和两个无效等价类,
- 如果输入条件是一个布尔类,可以定义一个有效率和一个无效率,
- 如果输入条件定义了输入值的集合,可以定义一个有效等价类和一个无效等价类,
- 如果规定了输入数据必须遵守的规则,则可以定义一个有效等价类和若干个无效等价类,
- 如果规定了输入数据的一组值,而且程序对不同输入值做不同处理,则可以定义若干有效等价类,和一个无效等价率,
- 如果确知已划分的等价类中,各元素在程序中的处理方式是不同,则应将此等价类进一步划分成更小的类,
等价分类法的步骤,
划分等价类,形成等价类表,
为每一个等价类规定一个唯一的编号,
设计一个新的测试用例,使其尽量多地覆盖尚未被覆盖的有效等价类,重复这一步,直到所有的有效等价类被覆盖为止,
涉及一个新的测试用例,使其覆盖一个,而且仅仅覆盖一个无效等价类,重复这一步,直到无效等价类均被覆盖为止,
- 边界值分析法,
边界值分析法主要用来选择等价类边界值作为测试用例,检查程序边界运行的情况,是一种补充等价分类法的测试用例设计技术,
如果输入条件代表以a和b为边界的范围,则测试用例应当包含ab,略小于下界a略大于上界b的值,
如果输入条件规定了值的个数,则用最大个数、最小个数、比最大个数多一、比最小个数少一、作为测试数据,
以此类推,
- 猜错法,
测试人员应依靠经验和直觉,从各种可能的方案中选出最可能引起程序出错的方案,
- 因果图法,
因果图法借助图形来设计测试用例,特别适合被测程序,具有多种输入条件程序的输出,又依赖于输入条件的各种组合的情况,
因果图法的分析步骤,
分析程序规格说明中哪些是原因,哪些是结果
分析程序,规格说明中描述的内容的语义和限制,找出两类关系画出因果图,
把因果图转换为判定表,
对判定表的每一列写成一个测试用例,
- 黑盒法综合策略,
首先用边界值分析法测试设计用例,
必要时用等价分类法补充测试用例,
必要时再用猜测法补充测试,
如果在程序的说明中含有输入条件的组合,应该在一开始就使用因果图法,随后再执行上述步骤,
7.5单元测试,
单元测试又称模块测试,是动态测试中的第1步,通常在编码模块进行,单元测试测试软件设计的最小单元模块,单元测试可以由程序作者进行,也可以由同行互测对方的单元,
- 测试策略,
单元测试一般把白盒子法和黑盒子法结合使用,先使用黑盒子法设计出一组基本的测试用例,然后用白盒子根据覆盖标准要求补充新的测试用例以满足覆盖标准,在一般的情况下,单元测试应该以白盒子法为准,
- 单元测试内容,
单元测试在于考察模块的接口和内部结构,主要检查以下几个方面的内容,
模块的接口,检查进出模块的数据是否正确,检查模块的实际输入是否一致,检查全局变量的定义在各个模块中是否一致等等,
局部的数据结构,检查局部数据能否保持完整性,比如变量可能从来没有被使用,不正确或不一致的变量说明,等等,
重要的执行通路,检查由于计算错误,判定错误,控制流错误导致的程序错误,比如死代码,错误的优先级等等,
出错处理路径,检查错误处理措施是否有效,检查错误是否出现?出现错误后是否进行处理?错误的处理是否有效?
影响以上各项的边界条件,检查临界数据是否正确的处理,比如普通合法数据是否正确处理,普通非法数据是否处理等等,
- 单元测试的阶段及活动,
完善测试计划阶段,制定方法资源及进度的计划,确定需测试与需求有关的特性,
获得测试用例阶段,获得测试用例集合,执行测试计划并实现设计,
评价检测单元阶段,执行测试流程,核对终止情况,评价测试效果和被测单元,
- 测试软件,
编写驱动模块和桩模块进行驱动测试,
一般的驱动模块应完成接收测试数据,并把数据传递给被测模块,然后打印有关结果,
桩模块应该模拟实际模块,完成少量的数据处理,并检测和打印入口处的信息,然后将控制返回给被测模块,
7.6集成测试,
集成测试又称组装测试,综合测试,是在单元测试完成之后,将所有模块按照概要设计要求组装成系统时进行的测试,
集成测试有两重意义,一方面将各模块拼装起来,形成可运行的系统,另一方面检查每一步拼装过程是否正确,
- 集成测试的测试内容,
主要检查模块接口和全局数据,比如,
穿越模块接口的数据是否会丢失?
一个模块是否对另一个模块产生不利的副作用?
模块组装后能否达到预期要求的功能
全局数据结构在引用中是否有问题?
模块的误差和积累是否可以接受?
- 集成测试的测试策略,
集成测试一般应由独立的测试小组进行,集成测试可以分为非建增式和建增式两种,在模块组装起来之后,模块之间的作用可能会导致新的错误,我们应该将已测试的测试用例重新执行一遍,称为回归测试,
- 非建增式测试,
采用非建增式测试,一般应先经过单元测试,然后再把所有的模块一次性组装在一起进行测试,
除非是很小的程序,否则一般用的很少,原因是模块一次性组合起来往往会产生很多的错误,导致难以定位错误的产生位置,
- 渐增式测试,
渐增式测试采用逐步加入模块或功能的方式进行,在加入过程中边连接边测试,比较容易定位和修正错误,
按照添加模块的方式,又可以分为自顶向下的键增势测试和自底向上的渐增式测试,
自顶向下的渐增式测试,首先集成主控模块,然后按照软件结构自上而下的进行集成,步骤如下,
- 以主控模块为被测模块间驱动模块,所有被主控模块直接调用的下层模块全部用装模块来代替,对主控模块进行测试,
- 根据集成的实现方法,用实际模块替换相应的装模块,再用装模块替代他们的直接下属模块,
- 在每一个模块集成的时候都要进行测试,
- 进行回归测试,排除组装过程中引入的新错误,
使用此种方式的优势有很多,比如能够较早的显示整个程序的轮廓,只需要编写装模块进行测试,能够尽早发现问题,但是也存在不利的条件,比如存在逻辑次序问题等,
自底向上的建增式测试,
- 把底层模块组合成实现某个特定的子功能的模块集合,并用编写的驱动程序控制它进行测试,可以对若干个功能集合并行的进行测试,
- 用实际模块替换掉驱动模块,沿软件结构自下而上移动,把子功能集合组合起来,形成更大的子功能集合,
- 重复12过程,直至组装完毕,
使用此种功能的优势是,软件测试只需要写驱动模块,不需要写装模块,在多数情况下,驱动模块的编写比桩模块要容易,缺点是程序的整体轮廓要在后期才能显现出来,
混合的渐增式测试
对于上层模块采用自顶向下的测试,对于某些关键模块或子系统采用自底向上的组装测试,一方面能减少对模块的重复测试次数,另一方面能够较容易地产生测试用例,
- 回归测试,
采用软件改动前测试时执行过的测试用例对改动后的软件再次进行测试,回归测试的用例有三种不同的类型,
能够测试软件的所有功能的代表性测试用例
针对可能会被修改所影响的软件功能,而进行附加测试的测试用例,
针对修改过的软件成分进行测试的测试用例,
7.7确认测试,
确认测试就是验证所开发的软件的功能和性能是否符合软件需求规格说明书的要求,所以测试又称为有效性测试,
一般在模拟的环境下,运用黑盒子法进行测试,
- 确认测试的内容,
功能测试,性能测试,强度测试,配置复审,
- 阿尔法测试和贝塔测试,
阿尔法测试是由一个用户在开发环境下进行的测试,也可以是开发机构内部的用户在模拟实际操作环境下进行了测试,阿尔法测试的目的是评审软件产品的,功能,局域化,可使用性,可靠性,性能,支持,
阿尔法测试可以从软件编码结束的时候开始,或者在软件模块完成测试后开始,也可以在确认测试过程中开始,
北塔测试是由软件的最终用户在一个或多个用户场所来进行,贝塔测试是开发者通常不在测试现场,在贝塔测试中,由用户负责记下所有的问题,定期向开发人员汇报,只有当阿尔法测试进行到一定的可靠程度时,才能进行贝塔测试,
贝塔测试的主要目的是,测试可支持性,文档,客户培训,
7.8系统测试,
系统测试是在更大范围内进行的测试,他将经过确认测试的软件作为整个基于计算机的系统的一个元素,与计算机硬件外设确认软件数据和人员等其他元素结合在一起,在实际运行环境下,对系统进行的一系列集成和确认测试,
- 恢复测试,
恢复测试就是通过各种手段让软件强制性的发生故障,然后验证恢复能否正常的进行,
如果系统的恢复是自动的,应该对系统重新初始化、数据恢复、重新启动、逐个进行评价,
- 安全性测试,
安全性测试用来验证集成在系统内部的保护机制,能否在实际中保护系统不受到非法侵入,主要的攻击手段有,
攻击易损坏的部分,破坏安全性,
有目的的引发系统出错,希望在系统恢复过程中侵入系统,
通过各种手段获取系统的密码,
浏览非保密数据,从中找到进入系统的方法,
- 可用性测试,
可用性测试,主要从系统使用的方便性与理解性,易学性等方面对系统进行检查,发现人为因素或使用习惯造成的问题,例如,用户界面是否便于使用?出错信息能否帮用户解决问题?销往国外的产品翻译是否完全?
- 安装测试,
安装测试是要找出系统安装过程中出现的问题,比如,系统硬件的配置是否合理?用户选择的一套任选方案是否相容?系统是否产生了所需的文件,系统是否每一部分都安装齐全?
- 互联测试,
互联测试需要验证两个或多个不同的系统之间的互操作性,这类测试对支持标准规格说明或承诺支持与其他系统互联的软件系统才有效,
7.9调试,
调试又称纠错或排错是程序测试后开始的工作,主要任务是依据测试发现的错误迹象,确定错误的位置和原因并加以改正,
- 调试的步骤,
从错误的外部表现形式入手确认错误出现的位置,
研究有关部分的程序,找出错误出现的内在原因,
修改设计和代码排除错误,
重复进行,暴露了这个错误的原始测试或某些相关测试,确认该错误是否被彻底排查,确认是否引进了新的错误,
如果修正无效,则撤销这个修正,重复上述动作,直到错误彻底解除,
- 猜测法,
该方法通过分析错误症状,根据以往经验辅助,已使用的计算机工具,猜测错误的原因并进行定位,
- 跟踪法,
先分析错误症状,然后确定最先发现错误的位置,人工岩程序的控制流程回溯程序代码,直到找到错误的根源,
跟踪法对于小型的程序非常有效,往往能把错误范围缩减到程序中的一小段代码,对于大程序,由于回溯的路径很多,此方法往往不是很有效,
- 演绎法,
测试人员首先根据已有的测试用例,设想及没举出所有可能出错的原因作为假设,然后再利用排除法排除掉错误的原因,最后再用测试数据验证余下的假设是否为出错的原因,
- 归纳法,
归纳法的基本思想是,从一些线索着手,通过分析他们之间的关系找出错误,
- 调试的原则,
冷静多思考,调试是软件过程中最艰巨的脑力劳动之一,调试人员要求要有耐心且细心,不会的时候可以厚着脸皮向他人请教,
彻底修改,一方面应注意其周围是否存在类似的其他错误,考虑错误的群集现象,另一方面要纠正错误的本身而不是其症状,
防止引入新的错误,进行回归测试来防止引入新的错误,
完结撒花!考试前两天再写一期关于画图的复习,下一个是马原的复习o((>ω< ))o