第七章-测试
1)了解软件测试的目标,测试的过程和步骤。
2)掌握软件工程测试阶段中单元测试、集成测试、确认测试中的相关内容。
3)掌握软件调试中的概念及主要工作,调试与测试的区别,调试的步骤及主要的调试方法。
4)掌握软件测试方法中白盒测试及黑盒测试原理,掌握等价类划分、边界值分析、路径覆盖、条件覆盖等测试用例设计技术。
1、测试基础
测试的目的:在软件投入生产性运行之前,尽可能多地发现软件中的错误。
测试的根本目标:尽可能多的发现并排除软件中隐藏的错误,最终把一个高质量的软件系统交给用户使用。
软件工程的根本目标:开发出高质量的完全符合用户需要的软件。
目前软件测试仍然是保证软件质量的关键步骤,它是对软件规格说明、设计和编码的最后复审。
测试决不能证明程序是正确的。
(1)软件测试在软件生命周期中横跨两个阶段。
- 通常在编写出每个模块之后就对它做必要的测试(称为单元测试),模块的编写者和测试者是同一个人,编码和单元测试属于软件生命周期的同一个阶段。
- 在这个阶段结束之后,对软件系统还应该进行各种综合测试,这是软件生命周期中的另一个独立的阶段,通常由专门的测试人员承担这项工作。
(2)软件测试的目标
- 测试是为了发现程序中的错误而执行程序的过程。
- 好的测试方案是极可能发现迄今为止尚未发现的错误的测试方案。
- 成功的测试是发现了至今为止尚未发现的错误的测试。
2、软件测试的方法
- 黑盒测试
把程序看作一个黑盒子,完全不考虑程序的内部结构和处理过程,是在程序接口进行的测试。 - 白盒测试
按照程序内部的逻辑测试程序,检测程序中的主要执行通路是否都能按预定要求正确工作。
3、软件测试的过程
- 单元测试
集中对用源代码实现的每一个程序单元进行测试,检查各个程序模块是否正确地实现了规定的功能。 - 组装测试
把已测试过的模块组装起来,主要对与设计相关的软件体系结构的构造进行测试。 - 确认测试
检查已实现的软件是否满足了需求规格说明中确定了的各种需求,以及软件配置是否完全、正确。 - 系统测试
把已经经过确认的软件纳入实际运行环境中,与其它系统成份组合在一起进行测试。
测试阶段的信息流:
单元测试
单元测试又称模块测试,是针对软件设计的最小单位——程序模块,进行正确性检验的测试工作。单元测试需要从程序的内部结构出发设计测试用例。多个模块可以平行地独立进行单元测试。
单元测试的内容:
在单元测试时,测试者需要依据详细设计说明书和源程序清单,了解该模块的I/0条件和模块的逻辑结构,主要采用白盒测试的测试用例,辅之以黑盒测试的测试用例使之对任何合理的输入和不合理的输入,都能鉴别和响应。
模块接口测试
在单元测试的开始,应对通过被测模块的数据流进行测试:
- 调用本模块的输入参数是否正确
- 本模块调用子模块时输入给子模块的参数是否正确
- 全局变量的定义和用法在各个模块中是否一致
在做内外存交换时要考虑:
- 文件属性是否正确
- OPEN与CLOSE语句是否正确
- 缓冲区容量与记录长度是否匹配
- 在进行读写操作之前是否打开了文件
- 在结束文件处理时是否关闭了文件
- 正文书写\输入错误
- I/O错误是否检查并做了处理
局部数据结构测试
- 不正确或不一致的数据类型说明
- 使用尚未赋值或尚未初始化的变量
- 错误的初始值或错误的缺省值
- 变量名拼写错误或书写错误
- 不一致的数据类型
- 全局数据对模块的影响
边界条件测试
使用刚好小于、刚好等于和刚好大于最大值或最小值的数据结构、控制量和数据值的测试方案,非常可能发现软件中的错误。独立路径测试
- 选择适当的测试用例,对模块中重要的执行路径进行测试
- 应当设计测试用例查找由于错误的计算、不正确的比较或不正常的控制流而导致的错误
- 对基本执行路径和循环进行测试可以发现大量的路径错误
出错处理测试
对错误的描述是难以理解的。
记下的错误与实际遇到的错误不同。
在对错误进行处理之前,错误条件已经引起系统干预。
对错误的处理不正确。
描述错误的信息不足以帮助确定造成错误的位置。模块的内聚程度高可以简化单元测试过程。
组装测试
在单元测试的基础上,将所有模块按照设计要求(如根据结构图)组装成为子系统或系统,进行集成测试。
需要考虑的问题:
- 在把各个模块连接起来的时候,穿越模块接口的数据是否会消失
- 一个模块的功能是否会对另一个模块的功能产生不利的影响
- 各个子功能组合起来,能否达到预期要求的父功能
- 全局数据结构是否有问题
- 单个模块的误差累计起来,是否会放大,从而达到不能接受的程度
在单元测试的同时可进行组装测试,发现并排除在模块连接中可能出现的问题,最终构成要求的软件系统。
子系统的组装测试特别称为部件测试,它所做的工作是要找出组装后的子系统与系统需求规格说明之间的不一致。
把模块组装成为系统的方式有两种:
一次性组装方式(非渐增式测试方法)
先分别测试每个模块,再把所有模块按设计要求放在一起结合成所要的程序。
操作比较困难,遇到的错误比较多。增殖式组装方式
把下一个要测试的模块同已经测试好的那些模块结合起来进行测试,测试完以后再把下一个应该测试的模块结合进来测试。
同时完成单元测试和集成测试
优点:
比较容易定位和改正错误;对接口可以进行更彻底的测试;可以使用系统化的测试方法。自顶向下集成:
从主控制模块开始,沿着程序的控制层次向下移动,逐渐把各个模块结合起来。在把附属于(及最终附属于)主控制模块的那些模块组装到程序结构中去时,或者使用深度优先的策略,或者使用宽度优先的策略。
该方式在测试过程中较早地验证了主要的控制和判断点。
深度优先的结合方法
- 先组装在软件结构的一条主控制通路上的所有模块。
- 选择一条主控制通路取决于应用的特点,并且有很大的任意性。
宽度优先的结合方法
- 沿软件结构水平地移动,把处于同一个控制层次上的所有模块组装起来。
步骤:
- 对主控制模块进行测试,测试时用存根程序代替所有直接附属于主控制模块的模块。
- 根据选定的结合策略(深度或宽度优先),每次用一个实际模块代换一个存根程序(新结合进来的模块往往又需要新的存根程序)。
- 在结合进一个模块的同时进行测试。
- 为了保证加入模块没有引进新的错误,可能需要进行回归测试(即全部或部分地重复以前做过的测试)。
优点:
- 不需要测试驱动程序
- 能够在测试阶段的早期实现并验证系统的主要功能
- 能在早期发现上层模块的接口错误
缺点:
- 需要存根程序
-可能遇到与此相联系的测试困难- 底层关键模块中的错误发现较晚
- 早期不能充分展开人力
自顶向下结合策略能够在测试的早期对主要的控制或关键的抉择进行检验。
自顶向下的方法讲起来比较简单,但是时间使用时可能遇到逻辑上的问题。
- 为了充分地测试软件系统的较高层次,需要在较低层次上的处理。
- 然而在自顶向下测试的初期,存根程序代替了低层次的模块,因此在软件结构中没有重要的数据自下往上流。
解决方法:
- 把许多测试推迟到用真实模块代替了存根程序以后再进行。
缺点:失去了在特定的测试和组装特定的模块之间的精确对应关系,这可能导致在确定错误的位置和原因时发生困难。- 从层次系统的底部向上组装软件。
自底向上集成:
混合增值方式
演变的自顶向下的增值测试
- 首先对输入/输出模块和引入新算法模块进行测试
- 接着自底向上组装成为功能相当完整且相对独立的子系统
- 然后由主模块开始自顶向下进行增殖测试
回归测试
这种方式采用自顶向下的方式测试被修改的模块及其子模块,然后将这一部分视为子系统,再自底向上测试。
确认测试
确认测试又称为有效性测试。
任务是验证软件的功能和性能及其它特性是否与用户的要求一致。
对软件的功能和性能要求在软件需求规格说明书中已经明确规定。它包含的信息就是软件确认测试的基础。
确认测试通常使用黑盒测试法。
(1)进行有效性测试(黑盒测试)
是在模拟的环境(可能就是开发的环境)下,运用黑盒测试的方法,验证被测软件是否满足需求规格说明书列出的需求。
- 首先制定测试计划,规定要做测试的种类。
- 还需要制定一组测试步骤,描述具体的测试用例。
通过实施预定的测试计划和测试步骤,确定
- 软件的特性是否与需求相符
- 所有的文档都是正确且便于使用
- 对其他软件需求,例如可移植性、兼容性、出错自动恢复、可维护性等,也要进行测试
在全部软件测试的测试用例运行完后,所有的测试结果可以分为两类:
- 相符:说明软件的这部分功能或性能特征与需求规格说明书相符合。
- 不符:说明软件的这部分功能或性能与需求规格说明书不一致,要为它提交一份问题报告。
(2)验收测试
在通过了系统的有效性测试及软件配置审查之后,应开始系统的验收测试。
- 验收测试是以用户为主的测试。软件开发人员和QA(质量保证)人员也应参加。
- 验收测试由用户参加设计测试用例,使用生产中的实际数据进行测试。
- 在测试过程中,除了考虑软件的功能和性能外,还应对软件的可移植性、兼容性、可维护性、错误的恢复功能等进行确认。