第一章
软件的定义
软件=程序+文档=数据+指令+文档
软件测试
- 软件测试是一组用来促进鉴定软件正确性、完整性、安全性和质量的过程。
- 换句话说,软件测试是一种实际输出与预期输出之间的审核或者比较过程。
- 经典定义: 在规定的条件下对程序进行操作,以发现程序错误,衡量软件质量,并对其是否能满足需求进行评估的过程。
第二章
开发者测试
- 包括
- 单元测试 <=> 详细设计
- 集成测试 <=> 体系结构设计
- 系统测试 <=> 软件需求
- 验收测试 <=> 客户需求
- Alpha和beta测试
- 回归测试
单元测试
- 侧重于核实软件的最小可测试元素
- 主要做功能正确的前提下的控制流和数据流的覆盖测试
- 目标
- 检验程序最小单元有无错误,如:接口、数据结构、边界、覆盖、逻辑
- 检验单元编码与设计是否吻合
集成测试
- 为什么进行集成测试?
- 一个模块可能对另一个模块产生不利的影响
- 将子功能合成时不一定产生所期望的主功能
- 独立可接受的误差,在组装后可能会超过可接受的误差限度
- 可能会发现单元测试中未发现的接口方面的错误
- 在单元测试中无法发现时序问题(实时系统)
- 在单元测试中无法发现资源竞争问题
- 分类
- 非增式
- 增式
- 自顶向下
- 自底向上
- “自顶向下”与“自底向上”的比较
- 什么时候能让测试者看到系统的框架
- 如何提供驱动模块和桩模块
- 生成测试数据的难易
- 什么时候暴露时序问题和资源竞争问题
系统测试
- 内容
- 软件系统之间的联合测试
- 软件、硬件等之间的联合测试
- 模拟真实运行环境的测试
- 目标
- 检验组成整个系统的代码、以及系统的软硬件配合有无错误
- 代码实现的系统与用户需求是否吻合
- 检验系统的各种文档等是否完整、有效
- 模拟验收测试的要求,检查系统是否符合用户的验收标准
α测试和β测试
- α测试是由用户在开发环境下进行的测试,由开发者随时记录下错误情况和使用中的问题
- β测试是一种验收测试,在实际使用环境下进行的测试.开发者通常不在测试现场,不能由程序员或测试员完成。
回归测试
- 目标
- 修改的或增加的部分是正确的
- 没有引起其他部分产生错误
- 应用
- 增量开发
- 版本控制
- 软件维护
软件测试过程
- 测试需求描述
- 测试计划
- 测试设计
- 用例
- 脚本
- 覆盖准则
- 测试开发
- 测试执行
- 测试结果与预期结果比较
- 测试充分性评估
- 测试报告生成
黑盒测试
- 黑盒测试被用来证实软件功能的正确性和可操作性
- 一种基于规格说明(Spec),不要求考察代码,以用户视角进行的测试
- 方法
- 基于图的测试
- 等价类划分
- 边值分析
- 比较测试
- 优点
- 黑盒测试与软件具体实现无关,所以如果软件实现发生了变化,测试用例仍然可以使用;
- 设计黑盒测试用例可以和软件实现同时进行,因此可以压缩项目总的开发时间
白盒测试
- 白盒测试用来分析程序的内部结构
- 基于代码,尽可能覆盖实现的行为
- 程序结构覆盖
- 语句覆盖:它要求被测程序的每一可执行语句在测试中尽可能都检验过,最弱
- 分支覆盖或判定覆盖:要求程序中所有判定的分支尽可能得到检验
- 条件覆盖:当判定式中含有多个条件时,要求每个条件的取值均得到检验
- 判定/条件覆盖:同时考虑条件的组合值及判定结果的检验
- 路径覆盖:只考虑对程序路径的全面检验
- 循环覆盖
第三章:黑盒测试用例设计
正面测试
- 证明软件对于每条规格说明和期望都能通过
- 通过正面测试用例产生一组预期输出验证产品需求
负面测试
- 产品没有设计、没有预想到的场景,尝试使系统垮掉
- 展示当输入非预期输入时,产品没有失败(fail)
等价类划分法
- 等价类:测试相同目标或暴露相同软件缺陷的一组测试
- 有效等价类:完全满足产品规格说明的输入数据;每个有效等价类都要覆盖
- 无效等价类:不满足程序输入要求或者无效的输入数据构成的集合;每个无效等价类都要单独覆盖
- 等价类划分准则
- 输入条件代表一组列表形式的数据,则可以定义N个有效等价类和一个无效等价类
- 输入条件代表要求符合某几个规则,则可以定义多个有效等价类和若干个无效等价类;
因果图(判定表)法
- 因果图的表示
- Ci表示原因,Ei表示结果,原因和结果的4种关系:
- 恒等(—)
- 非(~)
- 或(∨)
- 与(∧)
- 四种输入约束
- 互斥(E):多个原因不能同时成立,最多有一个能成立;即Ci不能同时为1
- 包含(I):多个原因中至少有一个必须成立;即Ci不能同时为0
- 唯一(O):多个原因中必须有一个且只有一个成立;即Ci只有一个为1
- 要求(R):当C1成立,C2也必须成立
- 一种输出约束
- 屏蔽(M):当E1是1时,E2必须是0;当E1是0,E2的值不定;
- Ci表示原因,Ei表示结果,原因和结果的4种关系:
- 过程 1. 生成因果图 2. 建立判定表 3. 生成测试用例
边界值分析法
- 软件的两个主要缺陷源:1)条件;2)边界
- 边界值附近数据的确认方法
- n: 存在边界值的参数个数
- m: 边界值条件数
- Paul Jorgensen公式
- 4n+1:基本边界测试:每个参数取min,min+1, max‐1,max各一次,同时其他参数取典型值nom。最后全部参数取典型值nom一次。
- 6n+1:健壮性边界测试: 每个参数取min‐1,min,min+1, max‐1,max,max+1各一次,同时其他参数取典型值nom。最后全部参数取典型值nom一次。
- 3m:条件边界测试:每个条件取‐1,自身,+1各一次。
- 每次只考虑一个参数的边界,固定其它参数
- 补充确定的关联边界值
第四章:白盒测试用例设计
为什么需要白盒测试
- 确保每段代码都被执行,避免相应的缺陷
- 是黑盒测试/功能测试的补充
- 能覆盖高层规范说明中的忽视的底层细节
- 更容易进行自动化测试。
静态白盒测试
- 技术评审technical review
- 代码/文档阅读code/document reading
- 走查/通查walk through
- 专项检查inspection
- 代码/数据/文档审计code/data/document audit
动态白盒测试
- 基于控制流测试方法
- 逻辑覆盖测试
- 基本路径测试
- 循环处理方法
- 基于数据流测试方法
测试覆盖准则
- 对“测试执行到何时才是充分的?”的定量回答
- 测试软件的一种度量标准,描述程序源代码被测试的程度。
逻辑覆盖测试
- 语句覆盖: 保证程序中的每条语句都执行一遍
- 判定覆盖: 保证每个判定取真取假至少一次
- 条件覆盖: 保证每个判定中的每个条件的所有可能结果都至少出现一次(取真取假至少一次)
- 条件覆盖不能保证程序所有分支都被执行
- 判定条件覆盖: 保证每个判定和每个判定中的每个条件的取值至少满足一次(取真取假至少一次)
- 条件组合覆盖: 保证每个判定中条件的各种可能组合都至少出现一次
- 2^n组合数目,n为原子条件数
- 路径覆盖: 保证每条可能执行到的路径都至少经过一次(如果程序中包含环路,则要求每条环路至少经过一次)
- 相对彻底,但不能替代条件覆盖和条件组合覆盖标准
- 路径条数可能以分支的指数级增加
基本路径测试
- 基本路径
- 指任何一条贯穿程序的路径,该路径至少包含一条不同于其他路径的边。
- 基本路径集合中路径条数唯一,基本路径可以不一样
- 其他路径可以通过基本路径运算得到
- 圈复杂度
- 度量基本路径数
- 是所有语句被执行一次所需测试用例数的上限
- 具有最高圈复杂度的模块蕴含错误的可能性最大,是测试中关注的焦点
- 计算:
- 等于域的数量
- V(G)=E-N+2, E为边,N为结点
- V(G)=P+1,P为判定结点数
- 基本路径集寻找算法
- 确认从入口到出口的最短路径
- 从入口到第1个未被先后评估为真和假两种结果的条件语句
- 改变该条件语句的判断值
- 按最短路径从这个条件语句到出口
- 重复步骤2-5,直到所有基本路径都被找到
循环处理方法
- 循环
- 简单循环
- 嵌套循环
- 串接循环
- 非结构循环
- 简单循环
- 跳过整个循环
- 只执行一次循环
- 执行两次循环
- 执行m(m < n)次循环
- 执行n-1,n,n+1次循环
- 嵌套循环
- 先测试最内层循环
- 所有外层的循环变量置为最小值
- 最内层按简单循环测试;
- 由里向外,测试上层循环:
- 此层以外的所有外层循环的循环变量取最小值
- 此层以内的所有嵌套内层循环的循环变量取“典型值”
- 该层按简单循环测试;
- 重复上一条规则,直到所有各层循环测试完毕
- 对全部各层循环同时取最小循环次数,或者同时取最大循环次数
- 先测试最内层循环
- 串接循环
- 若串接的各个循环互相独立:分别用简单循环的方法进行测试;
- 若两个循环不独立(第一个循环的循环变量与第二个循环控制相关),把第一个循环看作外循环,第二个循环看作内循环,然后用测试嵌套循环的办法来处理
基于数据流的测试
- 数据流是变量的定义或使用顺序和变量的可能状态的一种抽象表示。
- 数据流测试是一种面向变量定义位置-使用位置覆盖的基于程序结构的测试方法。
- 数据流测试的作用是用来测试变量定义位置和使用位置之间的路径。这些路径也 称为“定义-使用对”。
- 数据流覆盖测试步骤
- 对于给定的程序,构造相应的程序数据流图
- 找出所有变量的定义-使用路径
- 考察测试用例对这些路径的覆盖程度,即可作为衡量测试效果的度量值
- 定义
- 谓词使用P-use——USE(v,n)位于一个谓词中,即条件判断语句中
- 计算使用C-use——USE(v,n)位于一个计算中,即计算表达式中
- du-path
- 定义-清洁路径(define-clear-path/dc-path):如果变量v的某个定义-使用路径,除起始节点外没有其它定义节点,则该路径是变量v的定义-清洁路径
- Rapps和Weyuker标准
- All-Nodes:等价于语句覆盖
- All-Edges:等价于分支覆盖
- All-P-Uses:选择的路径中每个变量的每个定义节点都有一条dc-path到达该定义的每个P-use节点
- All-Defs:选择的路径中每个变量的每个定义节点都有一条dc-path到达该定义的某个使用节点
- All-P-Uses/Some C-Uses: 选择的路径中的每个变量的每个定义节点都有一条dc-path到达该定义的每个P-use节点;但如果没有可达P-use节点,dc-path应到达至少一个C-use节点
- All-C-Uses/Some P-Uses:选择的路径中的每个变量的每个定义节点都有一条dc-path到达该定义的每个C-use节点;但如果没有可达C-use节点,dc-path应到达至少一个P-use节点
- All-Uses:选择的路径中的每个变量的每个定义节点都有一条dc-path到达该变量的每个使用节点,若存在定义节点和使用节点间存在多条dc-path,仅选取其中一条。
- All-DU-Paths:所有的DU-Path集合。路径中的每个变量的每个定义节点到达该变量的每个使用节点的所有dc-path。若存在循环,仅取一个简单循环或者无循环。
- All-Paths:等价于路径覆盖
- 数据流异常
- 未初始化就读取了变量的值
- 根本没有使用变量的值
- 优点
- 揭示隐藏在代码变量定义和使用中的各种错误
- 可以覆盖所有语句、所有分支、所有路径
- 对代码的测试比较彻底
- 缺点
- 无法检测代码中不可达路径
- 不验证需求规格
第五章:回归测试
- 目的:为了保证在软件演化和维护时,那些未变更的代码的功能不会受影响
- 回归测试与一般测试比较,有六个方面不同:
- 测试计划
- 测试范围
- 资源分配
- 开发信息
- 完成时间
- 执行频率
- 过程
- 提出修改需求
- 修改软件工件(即软件制品artifact,文档、代码、模型等)
- 选择和生成测试用例(T1+T2)
- 执行测试
- 识别失败结果
- 确认错误
- 排除错误
- 策略
- 全部重新测试方法
- 有选择的重新测试方法
- 最常用:选择与某个特定模块相关的所有测试用例,及所有集成测试用例
- 波及效应分析的2种方法
- 字符串匹配
- 程序切片
第六章
面向对象软件开发方法的本质
- 一切都是对象
- 任务(/职责/功能)的完成是通过对象之间的协作达到的
面向对象测试
- 单元测试
- 两个常用的基本元素
- method
- class
- 测试方法与传统软件测试既类似又不同
- 两个常用的基本元素
- 集成测试
- 主要对系统内部的对象之间的协作进行测试,如成员函数间的相互作用,类间的消息传递等
- 因为面向对象程序具有动态绑定(dynamicbinding)特性,程序的控制流无法确定,只能对编译完成的程序做基于黑盒的集成测试
- 主程序最小化
- 基于合成/组合(composition)
- 使用类簇(class cluster),含继承
- 使用对象关系图(ORD: object relation diagram) – 类间依赖和方法依赖关系的有向图
- 面向对象技术的影响
- 类
- 基本可测单元
- 由模块集成变成类的集成
- 封装
- 修改封装会导致大量的回归测试
- 信息隐藏使对象的部分不可访问,减少了波动影响
- 测试顺序相当重要(可以减少工作量):集成测试序
- 继承
- 要确定衍类中从基类继承的已测试的功能是否需要再测试
- 多态
- 引入了不可判定性问题
- 一个多态组件的每一个可能的绑定都需要一个独立的测试,使得集成计划复杂化
- 抽象
- 抽象使测试变得困难,特别是要执行内部的结构测试时,降低了软件的可测试性。
- 面向对象的开发模型
- 迭代式增量开发过程模型
- 面向对象分析
- 面向对象设计
- 面向对象编程
- 在整个软件开发生命周期全过程中不断测试,分析一点、测试一点,设计一点、测试一点,编码一点、测试一点
- OSD(object state diagram)模型
- 基于状态测试使测试变得复杂,因此使用OSD
- 步骤
- 扫描源程序得出带执行条件的执行分析表
- 确定对象状态
- 构造转移
- 构造测试消息序列
- 根据每条测试消息序列,选择相应的数据进行测试
第七章:软件性能测试
软件性能定义
- 软件的一种非功能特性,
- 软件在运行的过程中表现出来的时间和空间效率与用户的需求之间的吻合程度
软件性能具体指
- 响应时间
- 系统响应时间:计算机对用户的输入或请求作出反应的时间
- 应用延迟时间(latency):是指应用接到指令后的处理时间。
- 吞吐量:是指系统在单位时间内处理请求的数量
- 并发用户数:是指系统可以同时承载的正常使用系统功能的用户的数量
- 资源利用率:反映的是在一段时间内资源平均被占用的情况
性能测试的方法
- 基准测试
- 负载测试(load testing)是检测在各种工作负载下系统的性能,也就是测试当负载逐渐增加时,系统各项性能指标的变化情况
- 压力测试(stress testing)是检测一个系统的瓶颈或者不能接受的性能点
- 容量测试(volume testing)是检测系统在给定时间内能够持续处理的最大负载或工作量
- 配置测试: 通过被测系统软/硬件环境的调整,了解各种不同环境对系统性能影响的程度,从而找到各项资源的最优分配原则。
- 可靠性测试
- 失效恢复测试
性能测试的步骤
- 熟悉应用
- 测试需求
- 测试准备
- 测试执行
- 测试结果分析
第八章
软件安全
- 安全可靠(safety):软件在运行过程中到达某个不安全的状态(例如触发了某个缺陷)导致了安全事故
- 正确性
- 稳定性
- 可靠性
- 安全保密(security):软件由于本身存在漏洞,被黑客利用发起攻击导致的安全事故
- 完整性:保护数据不被更改或破坏
- 机密性
- 可用性:确保资源被授权的用户使用
软件安全保障方法
- 先验方法
- 安全设计(原则)
- 安全风险预防、转移和回避策略
- 安全编程
- 威胁建模
- 后验方法
- 安全测试
- 安全分析
- 安全验证
第九章
ISO9126质量度量模型
- 功能性
- 可靠性
- 易使用性
- 效率
- 可维护性
- 可移植性
ISO 25010
新增
- 信息安全性
- 保密性
- 完整性
- 真实性
- 抗依赖性
- 可核查性
- 互用性
- 软件兼容性
- 数据兼容性
FURPS+模型
- 功能(function)
- 易用(usablity)
- 可靠度(reliablity)
- 性能(performance)
- 可支持性(supportablity)