测试基础
前言
- 所谓软件测试,就是一个过程或一系列过程,用来确认计算机代码完成了其应该完成的功能,不执行其不该有的操作
- 测试是为了发现错误而执行程序的过程(必须记住)
- “成功的”测试是指在测试某段程序时发现了错误,而且这些错误是可以修复的
- 所谓“不成功的”测试,仅指未能适当的对程序进行检查,在大多数情况下,未能找出错误的测试
- 软件测试是发现错误的过程,而不是为证明“软件做了其应该做的”过程
黑盒测试
- 黑盒测试又称为数据驱动的测试或输入/输出驱动的测试。将程序视为一个黑盒子,测试目标与程序的内部机制和结构完全无关,重点集中放在发现程序不按其规范正确运行的环境条件
- 测试数据完全来源于软件规范
- “穷举输入测试”,将所有可能的输入条件都作为测试用例。事实上,穷举输入测试是无法实现的。由于穷举测试是不可能的,测试投入的目标在于通过有限的测试用例,最大限度地提高发现的问题的数量,以取得最好的测试效果
白盒测试
- 白盒测试又称为逻辑驱动的测试,允许我们检查程序的内部结构。对程序的逻辑结构进行检查,从中获取测试数据
- 所谓穷举路径测试,即如果使用测试用例执行了程序中所有可能的控制流路径,那么程序有可能得到了完全测试
- 穷举路径测试存在的问题:
1、不能保证程序符合设计规范
2、程序可能会因为缺少某些路径而存在问题
3、可能不会暴露数据敏感错误
软件测试的原则
- 原则1:测试用例中一个必需部分是对预期输出或结果进行定义
- 原则2:程序员应当避免测试自己表写的程序
- 原则3:编写软件的组织不应当测试自己编写的软件
- 原则4:应当彻底检查每个测试的执行结果
- 原则5:测试用例的编写不仅应当根据有效和预期的输入情况,而且也应当根据无效和未预料到的输入情况
- 原则6:检查程序是否“未做其应该做的”仅是测试的一半,测试的另一半是检查程序是否“做了其不应该做的”
- 原则7:应避免测试用例用后即弃,除非软件本身就是一个一次性的软件
- 原则8:计划测试工作时不应假定软件或程序不会发现错误
- 原则9:程序某部分存在更多错误的可能性,与该部分已发现错误的数量成正比
- 软件测试是一项极富创造性、极具智力挑战性的工作
代码检查、走查和评审
代码检查与走查
- 代码检查、走查以及可用性测试是三种主要的人工测试方法
- 代码检查与走查都要求人们组成一个小组来阅读或直观检查特定的程序。在代码走查中,一组开发人员(3 到 4 人最佳)对代码进行审核,代码走查的主要工作是由其他人,而不是作者本人完成的
- 代码检查和走查是对过去桌面检查过程的改进。代码走查的另一个优点在于,一旦发现错误,通常就能在代码中对其进行精确定位,降低了调试(错误修改)的成本
代码检查
- 代码检查是以组为单位阅读代码,它是一系列规程和错误检查技术的集合
- 一个代码检查小组通常由四人组成,包括协调人、代码的作者、程序的设计人员以及一名测试专家
- 协调人的职责包括以下几点:
1、为代码检查分发材料、安排进程
2、在代码检查中起主导作用
3、记录发现的错误
4、确保所有错误随后得到修改 - 代码检查的目标是发现程序中的错误,从而改进软件的质量
用于代码检查的错误列表
代码检查过程的一个重要部分就是对照一份错误列表,来检查程序是否存在常见错误
代码走查
- 代码走查也是以小组为单位进行代码阅读,是一系列规程和错误检查技术的集合
- 小组由 3 到 5 人组成,一般包括协调人,秘书(负责记录所有查出的错误),测试人员
- 开始的过程与代码检查相同,参与者在走查会议的前几天得到材料,研读程序
- 不同于仅阅读程序或使用错误检查列表,代码走查的参与者“使用了计算机”,测试人员会带着一些书面的测试用例(程序或模块具有代表性的输入集及预期的输出集)
- 会议期间,把测试数据沿程序的逻辑结构走一遍,记录下程序的状态
- 测试用例提供了启动代码走查和质疑程序员逻辑思路及其设想的手段
- 在大多数的代码走查中,很多问题是在向程序员提问的过程中发现的,而不是由测试用例本身直接发现的
桌面检查
桌面检查是由一个人进行的代码检查或代码走查,阅读程序,对照错误列表检查程序,对程序推演测试数据
同行评审
同行评审是一种依据程序整体质量、可维护性、可扩展性、易用性和清晰性对匿名程序进行评价的技术
目的是让程序员对自身的编程技术进行自我评价
测试用例设计
- 软件测试过程中的关键就是设计和生成有效的测试用例
- 好的测试策略就是努力是测试尽可能完全
- 合理的测试策略是通过使用特定的黑盒测试用例设计方法,之后使用白和测试方法对程序的逻辑结构进行检查以补充测试用例
- 先使用黑盒测试方法来设计测试用例,然后根据实际情况需要使用白盒测试方法来设计补充测试用例
白盒测试用例设计方法
白盒测试关注的是测试用例执行的程度或覆盖程序逻辑结构的程度
- 语句覆盖
- 判定覆盖或分支覆盖
1、要求必须编写足够的测试用例,使得每一个判断都至少有一个为真和为假的输出结果,即每条分支路径都必须至少遍历一次
2、判定覆盖可以满足语句覆盖
- 条件覆盖
要编写足够的测试用例以确保将一个判断中的每个条件的所有可能的结果都至少执行一次 - 判定/条件覆盖
1、要求设计出足够的测试用例,将一个判断中的每个条件的所有可能的结果至少执行一次,将每个判断的所有可能的结果至少执行一次,将每个入口点都至少调用一次
2、缺点:某些条件的结果可能会屏蔽掉或阻碍其他条件的判断
3、条件覆盖或判定/条件覆盖准则不一定会发现逻辑表达式中的错误 - 多重条件覆盖
1、要求编写足够多的测试用例,将每个判定中的所有可能的条件结果的组合,以及所有的入口点都至少执行一次
2、满足多重条件覆盖准则的测试用例集,同样满足判定覆盖准则、条件覆盖准则以及判定/条件覆盖准则
黑盒测试用例设计方法
黑盒测试(数据驱动或输入/输出驱动的测试)基于程序规格说明书找出程序不符合规格说明书的地方
1、等价类划分
- 测试用例的特性:严格控制测试用例的增加,覆盖了大部分其他可能的测试用例
- 测试每个等价类的代表性数据等同于测试该类的其他任何数据
- 使用等价类划分方法设计测试用例主要有两个步骤:(1)确定等价类; (2)生成测试用例
- 确定定价类分为:有效等价类和无效等价类,有效等价类代表对程序的有效输入,而无效等价类代表不正确的输入
- 生成测试用例的过程:
(1)为每一个等价类设置一个不同的编号
(2)编写测试用例以覆盖所有可能的有效等价类
(3)编写测试用例以覆盖剩余所有的无效等价类
2、边界值分析
-
如果输入(输出)条件规定了一个输入值(输出值)范围,那么应针对范围的边界设计测试用例,针对刚刚越界的情况设计无效输入测试用例
-
如果输入(输出)条件规定了输入值(输出值)的数量,那么应针对最小数量输入值、最大数量输入值,以及比最小数量少一个、比最大数量多一个的情况设计测试用例
-
如果程序的输入或输出是一个有序序列,应特别注意该序列的第一个和最后一个元素
-
发挥聪明才智找出其它的边界条件
边界值分析方法与等价类划分方法存在两方面的不同:
(1)边界值分析需要选择一个或多个元素,以便等价类的每个边界都经过以此测试
(2)不仅考虑输入等价类,还需要考虑从输出等价类来设计测试用例
3、因果图
- 边界值分析和等价类划分的一个弱点是未对输入条件的组合进行分析
- 因果图可以指出规格说明的不完整性和不明确的地方
- 过程:
(1)将规格说明分解为可执行的片段
(2)确定规格说明中的因果关系,因是条件,而果是动作
(3)分析规格说明的语义内容,并将其转换为连接因果关系的布尔图
(4)给因果图加上注解符号
(5)将因果图转换成一个有限项的判定表(有难度),表中的每一列代表一个测试用例
(6)将判定表中的列转换成测试用例
- 因果图方法是一个根据条件的组合而生成测试用例的系统性的方法
缺点:不能生成全部应该被确定的有效测试用例,没有充分考虑到边界条件
4、错误猜测
- 利用直觉和经验猜测出错的可能类型,然后编写测试用例来找出这些错误
- 基本思想是列举出可能犯的错误或错误易发情况的清单,然后根据清单来编写测试用例
测试策略
- 每一种方法都可以提供一组具体的有用的测试用例,但是都不能单独提供一个完整的测试用例集
- 合理的测试策略:
1、如果规格说明中包含输入条件组合的情况,应首先使用因果图分析方法
2、在任何情况下都应使用边界值分析方法,对输入和输出边界的分析
3、应为输入和输出确定有效和无效等价类
4、使用错误猜测技术增加更多的测试用例
5、针对上述测试用例集检查程序的逻辑结构,应使用判定覆盖、条件覆盖、判定/条件覆盖或多重条件覆盖
单元(模块)测试
- 定义:对程序中的单个子程序、子程序或过程进行测试的过程。
是对最小功能点的测试 - 目的:将模块的功能与定义模块的功能规格说明或接口规格说明进行比较,确保模块被正确的编码,通常使用白盒测试,对代码风格和规则、程序设计和结构、业务逻辑等进行静态测试,及早的发现和解决错误
测试用例设计
- 需要模块的规格说明书和模块的源代码,规格说明一般都规定了模块的输入和输出参数以及模块的功能
- 面向白盒测试
- 使用一种或多种白盒测试方法分析模块的逻辑结构,然后使用黑盒测试方
- 法对照模块的规格说明以补充测试用例 表vcx5208]’
集成测试
- 定义:通过测试发现与模块接口有关的错误,是将所有程序模块进行有序的、递增的测试
- 目标是把通过了单元测试的模块组装成工作程序,当软件规模较大时,一般采用增量集成方式
- 非增量测试:先独立地测试每个模块,然后再将这些模块组装成完整的程序
- 增量测试:先将下一步要测试的模块组装到测试完成的模块集合中,然后再进行测试
- 增量测试的优点:
1、所需的工作量少一些
2、可以较早的发现模块中与不匹配接口、不正确假设相关的编程错误
3、调试容易一些
4、会将测试进行的更彻底
自顶向下测试
- 从程序的顶部或初始模块开始
- 原则:要成为合乎条件的下一个模块,至少一个该模块的从属模块(调用它的模块)事先经过了测试
- 采用什么样的形式将测试用例提交给程序
通过其一个或多个桩模块提交
自底向上测试
- 自底向上的策略开始于程序中的终端模块,测试完这些模块之后,下一个模块的所有从属模块都已经经过了测试
- 不足之处,没有早期程序框架的概念
比较
-
自顶向下测试的优点:
1、如果主要的缺陷发生在程序的顶层将非常有利
2、一旦引入 I/O 功能,提交测试用例会更容易
3、早期的程序框架可以进行演示,并可激发积极性 -
自顶向下测试的缺点:
1、必须开发桩模块
2、桩模块要比最初表现的更复杂
3、在引入 I/O 功能之前,向桩模块中引入测试用例比较困难
4、创建测试环境可能很难,甚至无法实现
5、观察测试输出很困难
6、使人误解设计和测试可以交迭进行
7、会导致特定模块测试的完全延后 -
自底向上测试的优点:
1、如果主要的缺陷发生在程序的底层将非常有利
2、测试环境比较容易建立
3、观察测试输出比较容易 -
自底向上测试的 缺点:
1、必须开发驱动模块
2、直到最后一个模块添加进去,程序才形成一个整体
执行测试
- 在测试执行之前应对测试用例集进行审核或检查,即对测试用例进行测试
- 使用自动化测试工具可以使测试过程中的枯燥劳动减到最小
- 单元(模块测试)的目的不是证明模块能够正确地运行,而是证明模块中存在着错误
确认(有效性)测试
- 目标:测试软件应有的功能是否实现
- 只有通过了确认测试之后的软件,才具备进入系统测试的条件
- 一般不作为正式的测试环节
系统测试
- 全面的,全方位的测试,是基于系统整体需求说明书的黑盒测试,包括系统所有功能的测试,模拟软件用户的操作,应覆盖系统所有联合的部件
- 是针对于整个产品系统经性的测试,目的是验证系统是否满足了需求规格的定义,找出与需求规格不相符或矛盾的地方
软件产品开发周期的模型:
1、需求规格说明定义了为什么要开发这个程序
2、目标定义了程序要做什么,以及应做的怎样
3、外部规格说明定义了程序对用户的准确表现
4、与后续阶段相关的文档详细地规定了程序是如何建立起来的
测试周期是模仿软件开发周期建立的,开发过程和测试过程是一对一的关系
- 功能测试的目的是为了证明程序未能符合其外部规格说明
- 模块测试的目的是发现程序模块与其接口规格说明之间不一致
- 系统测试的目的是为了证明软件产品与其初始目标不一致
软件测试的目标是发现问题
测试用例的15个分类
分类 | 说明 |
---|---|
能力测试 | 确保程序的目标功能实现 |
容量测试 | 发现处理大容量数据时的程序异常 |
强度测试 | 发现在大规模负载、高强度不间断持续的数据处理中的异常 |
可用性测试 | 评估最终用户在使用软件并与软件交互时的可用性问题 |
安全性测试 | 试图攻破程序的安全防线 |
性能测试 | 评估程序的响应时间及吞吐量瓶颈 |
存储测试 | 确保程序可以正确处理其对存储的需求,包括系统的存储和物理上的存储 |
配置测试 | 检查程序是否能在推荐配置上流畅运行 |
兼容性/转换测试 | 评估新版本是否能兼容老的版本 |
安装测试 | 确保能够在所有支持的平台上安装软件 |
可靠性测试 | 评估程序是否能达到规格说明书中的运行时常和MTBF(平均故障间隔时间)要求 |
可恢复性测试 | 测试系统恢复相关的功能是否按设计要求实现 |
服务/可维护性测试 | 评估系统是否拥有良好的数据处理和日志机制,以备技术支持和调试之需 |
文档测试 | 检验所有的用户文档是否正确 |
过程测试 | 对软件系统操作或维护所涉及的流程进行评估和确定 |
系统测试的执行
- 不能由程序员来进行系统测试
- 在所有的测试阶段之中,这是唯一一个明确地不能由负责该程序开发的机构来执行的测试
- 执行系统测试的人员思考问题的方式必须与最终用户相同,必须充分了解最终用户的态度和应用环境,以及程序的使用方式
- 理想的系统测试小组应由几位专业的系统测试专家,一位或两位最终用户的代表,一位人类工程学工程师以及该程序主要的分析人员或设计者所组成
- 最经济的执行系统测试的方式是将测试分包给一个独立的第三方公司来完成
安装测试
其目的不是为了发现软件中的错误,而是为了发现在安装过程中出现的错误
在安装软件系统期间会发生的事件:
- 用户必须选择大量的选项
- 必须分配并加载文件和库
- 必须进行有效的硬件配置
- 软件可能要去网络连通
安装测试应由生产软件系统的机构来设计,作为软件的一部分来发布,在系统安装完成之后进行
测试的计划与控制
- 目标
- 结束准则
- 进度
- 责任
- 测试用例库及标准
- 工具
- 计算机时间
- 硬件配置
- 集成
- 跟踪步骤
- 调试步骤
- 回归测试
测试结束准则
最常见的两个准则是:
- 用完了安排的测试时间后,测试便结束
- 当执行完所有的测试用例都未发现错误,测试便结束
三类较为有用的结束准则:
- 根据特定的测试用例设计技术
- 以确切的错误数量来描述结束测试的条件
在大型程序中,大约有40%的错误是编码和逻辑设计错误,剩下的错误则是产生于早期的设计阶段 - 直觉和经验
独立的测试机构
- 提升了测试过程中的积极性
- 建立了与开发机构的良好竞争
- 避免了测试过程处于开发机构的管理控制下,以及独立的测试机构带来的解决问题的专业知识
验收测试
- 指系统开发生命周期方法论的一个阶段,由相关的用户或独立测试人员根据测试计划和结果对系统进行测试和接受
- 将程序与其最初的需求及最终用户当前的需要进行比较的过程。通常是由程序的客户或最终用户来进行
- 设计测试用例,尽力证明程序没有满足合同要求,假如这些测试用例是不成功的,那么就可以接受该程序
α 测试
由用户在开发者的场所来进行的,在一个受控的环境中进行
β 测试
由软件的最终用户在一个或多个用户场所来进行的。开发者通常不在现场,用户记录测试中遇到的问题并报告给开发者,开发者对系统进行修改,之后发布上线
回归测试
- 定义;指在发生修改之后重新执行之前的测试用例以保证修改的正确性
- 目的在于验证以前出现过但已经修复好的缺陷不再重新出现