# Software Testing
**Repository Path**: xiaojiajia123456/software-testing
## Basic Information
- **Project Name**: Software Testing
- **Description**: 2021 滨海软件测试课程
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 159
- **Created**: 2021-09-23
- **Last Updated**: 2021-09-23
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 软件测试
## 写在最前面
### 1 课程目标
* 掌握基础的软件测试理论、测试方法和策略
* 掌握常用工具的使用方法
* 根据需求和设计文档,独立编写测试计划、测试方案、测试用例以及测试报告
### 2 主要内容
* 软件测试概论
* 软件测试基础知识
* 软件测试通用技术
* 软件测试流程
* 黑盒测试
* 白盒测试
* 性能测试
* 软件测试自动化
* 软件测试管理
### 3 课程安排
学时安排:72课时(理论36+实践36)
教材:清华大学出版社 《软件测试》(第2版) 周元哲 编著
### 4 课程资源
* 课程内容文档 [gitee 课程地址](https://gitee.com/XiaFuXiangFei/software-testing)
* 课程思维导图
* 测试相关文档模板
* 测试工具:[禅道](http://zentao.zrise.top/)
## 第1章 软件测试概论
### 1.1 软件
#### 1.1.1 软件定义
软件是一系列按照特定顺序组织的计算机数据和指令的集合。
**软件 ≠ 程序(代码)**
软件包含如下内容:
1. 运行时,能够提供所要求功能和性能的指令或计算机程序。
2. 程序能够处理信息的数据结构。
3. 用于描述程序功能需求、程序如何操作和如何使用的文档。
#### 1.1.2 文档
##### 开发文档
开发文档是描述软件开发过程,包括软件需求、软件设计、软件测试、保证软件质量的一类文档,开发文档也包括软件的详细技术描述、程序逻辑、程序间相互关系、数据格式和存储等。
* 《可行性研究》
* 《项目任务书》
* 《需求规格说明书》
* 《概要设计》
* 《详细设计》
* 《代码规范说明书》
* 《数据字典》
* 《开发计划》
##### 管理文档
从管理的角度规定涉及软件生存的信息:
1. 职责定义;
2. 开发过程的每个阶段的进度和进度变更的记录;
3. 软件变更情况的记录;
4. 相对于开发的判定记录。
* 《工作报告》
* 《工作日志》
* 《会议记录》
* 《里程碑报告》
* 《软件项目配置管理计划》
* 《实施方案》
##### 产品文档
为使用和运行软件产品的任何人规定培训和参考信息,促进软件产品的市场流通或提高可接受性。使得那些未参加开发本软件的程序员维护它。
* 《产品手册》
* 《用户指南》
* 《培训手册》
* 《软件支持手册》
#### 1.1.3 软件发展史
1. 程序设计阶段:个体化生产、专用软件、规模小、功能单一、开发者即使用者。(软件 = 程序);
2. 程序系统阶段:多用户人机交互,实时系统和数据库管理系统;
3. 软件工程阶段:以软件的产品化、系列化、工程化和标准化为特征的软件产业发展起来,软件开发有了可以遵循的软件工程化的设计准则、方法和标准;
4. 多层分布结构,面向服务架构。
#### 1.1.4 软件项目
软件项目是一种特殊的项目,具有如下特点:
1. 知识密集型,技术含量高;
2. 涉及多个专业领域,多种技术综合应用;
3. 项目范围广和目标的灵活性高;
4. 风险大,收益大;
5. 客户化程度高;
6. 过程管理重要。
### 1.2 软件生命周期
#### 1.2.1 需求定义
**描述:** 定义出本次任务都需要做什么,做成什么样子。
**参与者:** 产品经理、需求分析师、客户
#### 1.2.2 可行性分析
**描述:** 由项目组相关成员去研究需求是否可行,能不能做出来。
**参与者:** 产品经理、架构师、项目经理、开发人员
#### 1.2.3 需求分析
**描述:** 需求分析其实是在做需求细化,按照任务说明书中的任务内容和指标具体细化各个点,细化到每个输入框、每个按钮的样式,输入输出等各项值。
**参与者:** 产品经理、架构师、项目经理、测试人员/质量管理员(很多公司把这个统称为QA)、开发人员
**输出:**《需求规格说明书》
#### 1.2.4 评审
**描述:** 评审就是做审查,对这个阶段的工作进行审查,看是否偏离或者有遗漏(比如:设计和工厂的各个环节都有相关的审查,审查材料是否合格、设计是否符合规定、按照工人/设计出的材料需求是否足够或者多余等等,这些审查都是评审);评审一般由相应工作人员来参与。
**参与者:** 每个阶段的评审一般都是各职能部门内部审核,也可以申请其他相关人员审核,比如需求评审,一般是产品经理、项目经理、测试人员、开发人员一起评审;系统设计一般是项目经理、开发人员评审;测试策略评审一般是测试组内部评审等等
#### 1.2.5 设计
**描述:** 架构师根据需求确定产品或者项目的场景、特点,选择合适的框架,技术使项目实现最优化。在此基础上将系统进行概要设计,包括系统总体数据结构、数据库结构、模块结构以及它们之间的关系等。开发人员根据概要设计对具体模块进行详细设计,包括接口、参数等。此处设计会形成概要设计文档和详细设计文档。
**参与者:** 项目经理、架构师、开发人员、测试人员
#### 1.2.6 编码
**描述:** 开发人员根据详细设计文档对系统进行模块化开发,在确定参数和接口的情况下,根据需求对模块内部进行方法级别的设计和编码以及自测,对产品功能进行一一实现。
**参与者:** 开发
#### 1.2.7 提测
**描述:** 开发人员完成一个小迭代/小功能,且完成自测(开发编码完成后,一般都会自己检测一下),于是向测试部门发起提测,一般以邮件方式或者任务管理工具的任务流方式向测试部门通知xxx模块/功能可以测试。
**参与者:** 任务责任人(开发)、测试人员
#### 1.2.8 测试
- 测试需求
- 测试计划
- 测试设计
- 测试执行
- 回归测试
- 测试评估
#### 1.2.9 部署/发版
**描述:** 经过前面的各个阶段,产品已经可以出售或者面向大众了。配置管理人员进行封版、版本制作(针对产品来说)/部署上线(针对项目应用来说)。
**参与人:** 配置管理人员、测试人员
#### 1.2.10 支持维护
**描述:** 支持维护类似于我们日常中的售后,主要是对已卖出的产品/已上线的项目进行日常维护。包括纠错性维护和改进性维护两个方面。
**参与人:** 支持维护人员/售后工程师
### 1.3 软件测试概述
#### 1.3.1 软件测试定义
软件测试的经典定义是:在规定的条件下对程序进行操作,以发现程序错误,衡量软件质量,并对其是否能满足设计要求进行评估的过程。
IEEE(电气与电子工程师协会):使用人工或自动手段来运行或测定某个软件系统的过程,其目的在于检测他是否满足规定的需求或弄清预期结果和实际结果的差别。
#### 1.3.2 测试发展历程
1. 1957年之前-调试为主(Debugging Oriented)
软件规模小,复杂度低,开发人员承担需求分析、设计、开发、测试等所有工作,等同于调试。
2. 1957–1978-证明为主(Demonstration Oriented)
与调试区分开,这是软件测试史上一个重要的里程碑,主要目的是确认软件是满足需求的。
3. 1979–1982-破坏为主(Destruction Oriented)
1979年,《软件测试的艺术》 (The Art of Software Testing)第一版问世,这本书是测试界的经典之作。书中给出了软件测试的经典定义:
```
The process of executing a program with the intent of finding errors.
测试是为发现错误而执行程序的过程。
```
这个观点较之前证明为主的思路,是一个很大的进步。我们不仅要证明软件做了该做的事情,也要保证它没做不该做的事情,这会使测试更加全面,更容易发现问题。
4. 1983–1987-评估为主(Evaluation Oriented)
软件行业进入了大发展时期,软件趋向大型化、复杂化,质量越来越重要。软件测试的基础理论和实用技术开始形成。提出了在软件生命周期中使用分析、评审、测试来评估产品的理论。
5. 1988–至今-预防为主(Prevention Oriented)
尽量早地介入并发现这些明显的或隐藏的bug,发现得越早,修复起来的成本越低,产生的风险也越小。
#### 1.3.3 测试与开发的关系
**瀑布模型**

这是一种经典模型,提供了软件开发的基本框架。
强调开发工作(计划、设计、开发、测试、维护等)各阶段之间的先后顺序,不可以并行操作。
瀑布模型认为,测试是指代码完成后,处于运行维护阶段之前。如果需求和设计上存在缺陷,就会造成大量返工,增加成本。
为了更早的发现问题,测试应延伸需求评审,设计审查活动中,软件生命周期的每个阶段都应包含测试。
**优点:**
1. 各阶段划分清晰;
2. 强调计划与需求分析;
3. 适合需求稳定的产品开发。
**缺点:**
1. 单一流程,不可逆;
2. 风险显露得晚,纠正机会少;
3. 测试只是其中一个阶段,缺乏全过程测试思想。
**V模型**

强调将测试和开发同等重要,对于开发阶段都有与之对应的测试阶段。
**优点:**
相对于瀑布模型,V模型测试能够尽早的进入到开发阶段。
**缺点:**
虽然测试尽早的进入到开发阶段,但是真正进行软件测试是在编码之后,这样忽视了测试对需求分析、系统设计的验证,时间效率上也大打折扣。
**W模型(双V模型)**

明确表示出了测试与开发的并行关系。
**优点:**
W 模型相对于 V 模型来说,测试更早的进入到开发阶段,与开发阶段是并行关系,更早的发现问题,能够及时解决问题,各个阶段分工明确,方便管理。
**缺点:**
W 模型是顺序性的、不可逆的,需求的变更和调整,依旧不方便。
**螺旋模型**

大型软件项目通常有很多不确定性和风险,如果采用瀑布式线性过程模型,失败风险很大,因此需要采取一种渐进式的演化过程模型。将产品分解成增量版本,每个版本单独测试。
**敏捷模型**

敏捷开发以用户的需求进化为核心,采用迭代、循序渐进的方法进行软件开发。专注于交付对客户有价值的软件(可以工作的)。
强调以人为核心,程序员团队和业务专家之间的紧密联系,频繁交付新的软件版本,紧凑的自我组织型团队,更注重软件开发中人的作用。
在敏捷开发中,软件项目在构建初期被切分成多个子项目,各个子项目的成果都经过测试,具备可视、可集成和可运行使用的特征。换言之,就是把一个大项目分为多个相互联系,但也可独立运行的小项目,并分别完成,在此过程中软件一直处于可使用状态。
**《联盟敏捷宣言》**
1. 最重要的是通过尽早和不断交付有价值的软件满足客户需要;
2. 我们欢迎需求的变化,即使在开发后期;敏捷过程能够驾驭变化,保持客户的竞争优势;
3. 经常交付可以工作的软件,从几星期到几个月,时间尺度越短越好;
4. 业务人员和开发者应该在整个项目过程中始终朝夕在一起工作;
5. 围绕斗志高昂的人进行软件开发,给开发者提供适宜的环境,满足他们的需要,并相信他们能够完成任务;
6. 在开发小组中最有效率也最有效果的信息传达方式是面对面的交谈;
7. 可以工作的软件是进度的主要度量标准;
8. 敏捷过程提倡可持续开发;出资人、开发人员和用户应该总是维持不变的节奏;
9. 对卓越技术与良好设计的不断追求将有助于提高敏捷性;
10. 简单——尽可能减少工作量的艺术至关重要;
11. 最好的架构、需求和设计都源自自我组织的团队;
12. 每隔一定时间,团队都要总结如何更有效率,然后相应地调整自己的行为。
**解读:**
* 个体和互动高于流程和工具
以人为本,没有比面对面交流更高效的沟通渠道了,基于互相信任的前提,敏捷提倡自治的全功能团队。
在工作形式上,整个团队平时坐在一起工作,从物理空间上创造了更加便捷面对面的沟通机会。在团队职责上,团队内部具备完成软件交付的角色(能力),团队所有人对软件的质量负责,开发过程由团队内部把控,业务价值团队内部快速流动,在任何环节都能及时获得反馈。同时,每个角色都更容易从全局视角去思考软件,避免了传统部门墙模式下的视角割裂和协作障碍。
* 工作的软件高于详尽的文档
为客户交付可工作的软件是我们的核心目标,我们应该尽早交付可进行端到端测试的代码,该目标决定了我们不应该花过多精力在面面俱到的文档上,但这不代表我们要抵制任何文档。实践证明,轻量级的文档策略有助于团队高质量交付可工作的软件。
* 客户合作高于合同谈判
主动拥抱变化,及时响应,持续交付。
* 响应变化高于遵循计划
通过高效的协作,获取快速的反馈,从而尽早做出调整,减少浪费。
**缺点:**
由于其项目周期很长,所以很难保证开发的人员不更换,而缺少文档就会造成在交接的过程中出现很大的困难。

### 1.4 软件缺陷
#### 1.4.1 缺陷定义
IEEE729-1983 (电气和电子工程师协会标准IEEE) 对缺陷有一个标准的定义:从产品内部看,缺陷是软件产品开发或维护过程中存在的错误、毛病等各种问题;从产品外部看,缺陷是系统所需要实现的某种功能的失效或违背。
符合下面4个条件之一就是缺陷:
1. 软件未达到规格说明书中规定的功能;
2. 软件出现了产品说明书中指明的不会出现的错误;
3. 软件功能超出了产品说明书中指明的范围;
4. 软件难于理解,不易使用,运行速度慢,或者最终用户认为软件使用效果不好。
#### 1.4.2 产生原因
1. 软件本身复杂性,产生大量不确定因素;
2. 成本、时间限制,导致流程不够完善,文档缺失,缺乏严谨的评审;
3. 人员本身技能水平、责任心、交流沟通不顺畅;
4. 不全面或者没有复审。
#### 1.4.3 缺陷来源
| 缺陷来源 | 描述 |
| ------------ | -------------------------------- |
| 需求说明书 | 需求说明书错误或描述不清 |
| 设计文档 | 设计文档描述不准确,与需求不一致 |
| 系统集成接口 | 各模块参数不匹配 |
| 数据流(库) | 数据字典、数据库中的错误 |
| 程序代码 | 编码问题 |
#### 1.4.4 缺陷类型
| 缺陷类型 | 描述 |
| -------- | ------------------------------------------------ |
| 功能 | 未达到规格说明书中规定的功能,影响系统使用 |
| 用户界面 | 未按照原型设计,影响交互,如:显示格式,按钮位置 |
| 文档 | 文档内容不完整或不正确,影响发布和维护 |
| 软件包 | 由于软件配置库、变更管理或版本控制引发的错误 |
| 性能 | 执行时间长、处理速度慢、负载高等方面 |
| 接口 | 与其他模块参数不匹配 |
#### 1.4.5 缺陷级别
**严重性:** 表示软件缺陷的恶劣程度,当用户碰到该缺陷时影响的可能性和程度。
**优先级:** 表示修复缺陷的重要程度和紧迫程度。
##### 严重性
| 级别 | 名称 | 说明 | 示例 |
| :---: | :------: | :----------------------------------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| S1 | 致命错误 | 严重阻碍开发或测试工作的进行,必须马上解决 | 安装包或App无法安装
网页不能访问
不能启动
死机
核心功能无法使用,比如QQ不能收发消息,邮箱不能收发邮件 |
| S2 | 严重缺陷 | 系统出现重大问题,影响提供的主要功能使用 | 内存泄露
数据无法保存 |
| S3 | 主要错误 | 主要功能实现有问题,易用性不够好 | 某个非核心功能全部或者部分未实现、实现后流程走不通、实现的功能与需求不同、文本框未校验或者校验不全、提示不全(异常提示不合理或者没提示)、手册相关内容缺失、兼容问题、安装界面乱码 |
| S4 | 次要错误 | 次要功能实现有问题或者手册相关问题 | 个别不常用的属性不生效或实现有问题(前提:不影响主要功能使用)
次要功能实现与需求不符或实现有问题(如:日志不能轮转、预警策略不生效、搜索框不能用、快照生成格式有问题等)
错别字
手册描述不合理或样式格式有问题 |
| S5 | 轻微缺陷 | 建议,不属于缺陷 | |
##### 优先级
| 级别 | 名称 | 说明 |
| :---: | :---: | ----------------------------------------------------------------------------- |
| P1 | 低 | 不影响整个系统的正常运行,一般指建议性的问题 |
| P2 | 中 | 不影响继续测试,但也是必须要修改的,对功能的实现有所影响,如果时间允许应该修复 |
| P3 | 高 | 影响整个测试的继续进行,要马上修改 |
| P4 | 急 | 系统无法继续执行下去,必须立即修改 |
严重性和优先级对于审查缺陷报告并决定哪些软件缺陷应该修复,以何种顺序修复的人员极为重要。如果一个程序员受命修复10个缺陷,他就应该先从严重性为1 、优先级为4这样的缺陷着手,而不是优先修复简单的,由简到难。
综合使用重要性等级和严重性双标准的优先顺序:
| | S1. 致命错误 | S2. 严重缺陷 | S3. 主要错误 | S4. 次要错误 | S5. 轻微缺陷 |
| :----: | ------------------- | ------------------- | -------------------- | ------------------- | ------------------- |
| P4. 急 | 立即修复
3小时内 | 第2修复
1天内 | 第4修复
2天内 | 第7修复
3天内 | 第11修复
4天内 |
| P3. 高 | 第3修复
1-2天内 | 第5修复
2-3天内 | 第8修复
3-4天内 | 第12修复
4-5天内 | 第15修复
5-6天内 |
| P2. 中 | 第6修复
3-4天内 | 第9修复
4-5天内 | 第13修复
5-6天内 | 第16修复
6-7天内 | 第18修复
2-3周内 |
| P1. 低 | 第10修复
8-7天内 | 第14修复
7-9天内 | 第17修复
8-12天内 | 第19修复
3-4周内 | 第20修复
择期 |
#### 1.4.6 跟踪流程
最优化、最简单的生命周期是:(理想情况)
1. 测试员发现缺陷并记录缺陷报告;
2. 缺陷报告交给程序员,此时缺陷状态是打开;(open state)
3. 程序员修改缺陷,此时缺陷状态是解决;(resolved state)
4. 缺陷报告交还测试员;
5. 测试员确认已修复;
6. 测试员关闭缺陷报告,此时缺陷状态是关闭。(closed state)
一个缺陷很可能会被反复打开→关闭。在日常工作过程中,由于开发修订其他缺陷影响、需求变更等因素缺陷可能会被反复打开→关闭。
| 缺陷状态 | 描述 |
| -------- | -------------------------------------------------- |
| 打开 | 确认提交的缺陷,等待处理 |
| 已分配 | 分配开发人员进行修复 |
| 已解决 | 经过开发人员修复,等待测试人员验证 |
| 已验证 | 测试人员验证修复成功 |
| 已关闭 | 修复完成,确认测试通过 |
| 重新打开 | 测试验证依然存在缺陷,等待开发修复 |
| 推迟 | 暂不解决,可能在下一个版本修复 |
| 保留 | 条件不允许,不能修复 |
| 不能重现 | 开发不能复现这个缺陷,需要测试人员检查缺陷发现步骤 |
#### 1.4.7 缺陷记录内容
1. bug编号:bug的唯一id,以方便尽快找到此bug;
2. bug标题:bug摘要,阐述bug大体内容;
3. bug严重级别,优先级:作为缺陷是否修复以及缺陷修复优先级的决定性因素;
4. bug产生的模块:记录bug所属模块,方便开发定位问题;
5. bug对应的版本:bug对应的软件版本,方便后续的统计归档以及开发定位问题;
6. bug描述:bug的产生环境、详细步骤、期望结果、实际结果;
7. 附件:包括但不仅限于截图、日志、录像、所用到的示例文件以及应用;同样是方便复现解决缺陷的。
以上是上报bug、创建bug必须要做的,在后续我们还会对bug进行修复、复测等工作,那么为了记录后续工作,bug还应该包含:
1. bug状态:开始、修复中、修复完成、提测、测试中、测试通过/失败、关闭等,后续bug周期中会讲到;
2. bug修订人:bug修订人员;
3. bug复测人:通常是谁报的bug最后返回给谁测试,但是在某些情况下比如bug报告人任务积累太多/不在的情况下也会分给其他人,所以通常会记录bug复测责任人;
4. bug修订说明:由bug修订人来写,说明bug产生原因,修改思路等;
5. bug复测说明:由复测人员来写,说明复测过程,复测结果等;
6. bug备注:备注,以便记录一些额外信息。
#### 1.4.8 缺陷预防
**差错:**人在理解和解决问题的思维和行为过程中出现的问题,沟通不当,理解错误;(产生根源)
**错误:**软件内部问题,设计错误、编码错误;(内部原因)
**失效:**软件系统运行时偏离了用户需求。(外部表现)
### 1.5 软件测试行业
#### 1.5.1 行业现状
软件系统越来越复杂,一个软件不能够由单独的软件工程师单独编写,而是由团队进行配合,每个人可能只负责一个模块,对于全局没有过多的了解,这时如果运行软件就会容易产生很多的错误。在行业内将这些错误叫做BUG。并且每一个软件工程师都会有思维的死角,自己不容易发现自己编写出来的错误。所以这个时候就需要专门的软件测试工程师用专业的测试方式来检查软件。检查该软件是否符合客户要求的产品设计,是否能够符合大多数用户的使用习惯,如果发现异常状态及时进行处理。软件市场虽然远远没有达到饱和但是各种各样功能的软件也层出不穷竞争激烈,对软件开发的质量要求也是日益增高。
我国软件测试行业起步较晚,发展较慢,直到21世纪初期,我国才逐步开始重视软件测试行业。但近年来,软件行业的快速发展为软件测试行业的发展提供了良好的基础,随着我国软件测试行业的发展,行业内企业向规模化发展将获得规模效应,可以有效降低企业的单位成本;而软件测试技术的不断发展,也将淘汰那些技术实力较弱的企业,促使行业内企业向专业化方向发展。
在软件业较发达的国家,软件测试产业已形成规模,比较发达,软件测试不仅早已成为软件开发的一个重要组成部分,而且在整个软件开发的系统工程中占据着相当大的比重。在微软公司内部,软件测试人员与软件开发人员的比例一般为1.5∶1到2.5∶1左右,即一个开发人员背后,有至少两位测试人员在工作,以保证软件产品的质量。国外优秀的软件开发机构把40%的工作花在软件测试上,软件测试费用占软件开发总费用的30%至50%,对于一些要求高可靠性、高安全性的软件,测试费用甚至相当于整个软件项目开发所有费用的3至5倍。
从国内软件公司软件测试部门的独立性来看,多数软件企业没有专门的测试技术部门,软件测试程序也不太规范,多数企业也不懂测试,对测试的投入资金过少。大多数是在经过简单地测试之后,就认为没有问题了,就交于用户了,让用户去“测试”。于是,软件产品在没有经过严格测试的情况下就发布了。对国内消费类软件而言,经常出现一些已经推向市场的产品由于被发现有严重缺陷而导致大量退货的现象。定制的行业软件,常出现一再返工、无限期的修改和维护的现象。
当前国内软件测试行业主要存在以下问题:
1. 软件规模越来越大,功能越来越复杂,如何进行充分而有效的测试成为难题;
2. 面向对象的开发技术越来越普及,但是面向对象的测试技术却刚刚起步;
3. 对于分布式系统整体性能还难以进行很好的测试;
4. 对于实时系统缺乏有效的测试手段;
5. 随着安全问题的日益突出,信息系统的安全性如何进行有效的测试与评估,成为世界性的难题;
6. 测试的自动化程度不高,手工测试过多,自动化测试工具和手工测试人员也缺乏较好的结合;
7. 缺乏软件测试意识,对其重视不够;
8. 在软件开发基本完成后才进行测试,也缺乏软件测试的统一标准;
9. 高校从师资储备到专业设置再到人才培养的机制薄弱。
国内外软件测试差距
1. 测试的理解认识;
2. 测试过程的管理;
3. 测试工具的使用;
4. 测试人员的培养。
#### 1.5.2 未来趋势
1. 以软件为代表的计算机行业正在以一种井喷式的趋势发展;
2. 人才缺口大;
3. 女性员工受到青睐;
4. 未来发展空间大;
5. 外包为主。
#### 1.5.3 软件测试职业发展
1. 技术方向
- 敏捷测试专家
- 高级测试开发专家
- 专项测试专家
- QA-Ops 专家
2. 管理方向
- 测试组长
- 测试经理
- 项目测试负责人
- 测试总监
3. 易转型方向
- 项目经理
- 产品经理
#### 1.5.4 测试思维方式
1. 逆向思维方式
2. 组合思维方式
3. 全局思维方式
4. 两级思维方式
5. 比较思维方式
6. 发散思维方式
### 1.6 测试认识的误区
1. 使用了测试工具,就是进行了有效的测试;
>有效的测试首先是指该软件具有可测试性。可测试性反映了软件质量的内在属性,是一个强内聚、弱耦合、接口明确的软件,它不会因为使用了某种测试工具,就证明被测试的软件具有可测试性。
2. 存在太多无法测试的东西;
>在软件开发领域,确实存在一些看起来比另外一些东西难测试的东西,但是远非无法测试。在大多数情况下,发生这种情况还是由于被测试软件本身在设计时没有考虑到可测试性的问题。只不过这种不可测试性不是由于被测试软件内部的过紧耦合造成的,而是和外部某些很难测试的部分耦合过紧,从而表现出被测试软件本身很难测试的特征。这些很难测试的部分,比较常见的有图形界面、硬件、数据库等。
3. 软件开发完成后才进行测试;
>软件测试是一个系列过程活动,包括软件测试需求分析、测试计划设计、测试用例设计、执行测试,软件测试贯穿软件项目的整个生命过程,每一个阶段都要进行不同目的和内容的测试活动,以保证各个阶段的正确性。软件测试的对象不仅仅包括软件代码,还包括软件需求文档和设计等各类文档。软件开发与软件测试是交互进行的,例如,单元编码需要单元测试,模块组合阶段需要集成测试。如果等到软件编码结束后才进行测试,测试的时间将会很短,测试的覆盖面将很不全面,测试的效果也将很差。更严重的是,如果发现了软件需求阶段或概要设计阶段的错误,要修复该类错误,将会耗费大量的时间和人力。
4. 软件发布后发现质量问题,是测试人员的问题;
>这种错误的认识非常伤害软件测试人员的积极性。软件中的错误可能来自软件项目中的各个过程,软件测试只能确认软件存在错误,不能保证软件没有错误,因此从根本上讲,软件测试不可能发现全部错误。从软件开发的角度看,软件的高质量不是软件测试人员测出来的,是靠软件生命周期的各个过程中设计出来的。如果出现软件错误,不能简单地归结为某一个人的责任,有些错误可能是技术原因,也可能是混乱的管理所致。因此,应该分析软件项目的各个过程,从过程改进方面寻找产生错误的原因和改进的措施。
5. 软件测试很简单,就是点点点,是个人就能做;
>随着软件工程学的发展和软件项目管理经验的提高,软件测试已经形成了一个独立的技术学科,演变成一个具有巨大市场需求的行业。软件测试技术不断更新和完善,新工具、新流程、新方法都在不断出现。因此,软件测试需要学习很多测试知识,更需要不断的实践经验和学习精神。
6. 软件测试没有前途,只有程序员才是软件高手;
>随着市场对软件质量要求的不断提高,软件测试将变得越来越重要,对测试人员的要求也越来越高。测试人员不仅要懂得如何测试,还要懂得被测软件的业务知识和专业知识。而开发人员往往只需要对自己开发的模块了解比较深,对算法掌握的程度要求高一些,所以,软件测试和开发人员只是工作的侧重点不同,并不存在水平差异的问题。
7. 软件测试是测试人员的事情和程序员无关;
>开发和测试是相辅相成的过程,需要测试人员、程序员和系统分析师等保持密切的联系,需要交流和协调,以便提高测试效率。另外,对于单元测试,主要应该由程序员完成,必要时测试人员可以帮助设计测试样例。对于测试中发现的软件错误,很多都需要程序员通过修改编码才能修复。程序员通过有目的地分析软件错误的类型、数量,找出产生错误的位置和原因,以避免同样的错误发生,积累编程经验,提高软件开发能力。
8. 项目进度吃紧时少做测试,时间多时多做测试;
>这是在软件开发过程中不重视软件测试的常见表现,也是软件项目过程管理混乱的表现,必然会降低软件测试的质量。软件项目开发需要合理的项目进度计划,其中就包括测试计划,对项目实施过程中的任何问题,都要有风险分析和相应的对策,不要因为开发进度的延期而简单地缩短测试时间,压缩人力和资源。因为缩短测试时间使测试不完整,引入潜在风险,往往造成更大的软件缺陷。避免这种现象的最好办法是加强软件过程的计划和控制,包括软件测试计划、测试设计、测试执行、测试度量和测试控制。
9. 测试要进行穷尽测试;
>测试最多只是采样。
10. 采样是随机抽取过程;
>测试采样过程需要使用正确的测试用例设计方法来操作。
11. 测试和开发是对头;
>开发和测试是合作伙伴的关系,在日常生活中要注意沟通技巧和方式,如意见不一致且不能说服对方的问题,上报给负责人去决定。
12. 测试少报bug开发就会高兴点,报告也会好看点;
>遇到缺陷一定要上报,即使他不能稳定复现(当然测试要尽可能的再现缺陷,并且找出再现问题的具体步骤)。但是一定不要不负责任的乱报。
13. 自动化测试终会取代手工测试;
>我们在选择用哪种方法的测试的时候,坚持“效率最高化,利益最大化”的原则来选择用最适合的方法。我们工作的目的是为了利益,而不是显得高端。
>
>自动化测试的初衷是将测试从繁重的、重复的回归工作中解放出来,从而提高测试效率的。并不是为了取代手工测试的,当然以目前的情况来看也取代不了手工测试。另外自动化测试需要在前期投入大量的人力资源和时间,且维护成本很高,故不能盲目推崇测试自动化。
||手工测试|自动化测试|
|----|----|----|
|概念|手工测试是由专门的测试人员从用户视角来验证软件是否满足设计要求的行为,更适合用于深度的测试和强调主观判断的测试。|自动化测试利用测试工具软件来控制测试的自动化执行以及对预期和结果进行检查。一般来说单元测试、接口测试和性能测试等就是利用自动化测试完成。|
|优点|易发现缺陷
容易实施
创造性、灵活性|高效率、速度快
高复用性
覆盖率容易度量
准确、可靠
不知疲劳|
|缺点|覆盖量化难
重复测试效率低
不一致性,可靠性低
人力资源依赖|机械、发现缺陷率低
一次性投入较大
对人员要求高|
14. 规范化软件测试是增加项目成本;
>大家常说“磨刀不误砍柴工”,但是真正用时又拿“能省则省”的理论来操作,殊不知此时省了相当于埋了颗雷。不仅要规范化软件测试,更要规范化整个软件过程,规避个人水平、责任心、经验的差距。
15. 测出bug越多测试越有效;
>测试过程中bug的数量并不能说明测试的有效性,只能说明开发人员的技术水平高低。项目上线后/产品卖出后现场反馈回来的线上bug数量才能反应测试的有效性。
16. 软件测试工作只负责项目上线/产品发布之前的部分。
>测试活动贯穿整个软件生命周期。
### 1.7 知识点总结
1. 软件定义与发展
2. 软件测试定义与发展
3. 软件生命周期
4. 软件测试模型
5. 缺陷定义、来源、产生原因和记录方法
6. 软件测试行业
7. 软件测试职业发展
8. 软件测试认识误区
## 第2章 软件测试基础知识
### 2.1 概述
1. 从软件测试的目的来理解
软件测试的目的是发现软件中的错误,是为了证明软件有错,而不是无错。是在软件投入运行前,对软件需求分析、设计和编码各个阶段产品的最终检查,是为了保证软件开发产品的正确性、完整性和一致性。
2. 从软件测试的性质来理解
在软件开发过程中,分析、设计和编码都是“建设性的”,唯有测试是“破坏性的”。
3. 从软件开发角度来理解
软件测试以检查产品的内容和功能特性为核心,是软件质量保证的关键步骤,也是成功实现软件开发目标的重要保障。
4. 从软件工程角度来理解
软件测试是软件工程的一部分,是软件工程过程中的重要阶段。
5. 从软件质量保证角度来理解
软件测试是软件质量保证的重要措施。
### 2.2 测试的目的和原则
#### 2.2.1 测试的目的
1. 测试不仅仅是找出错误。通过分析错误产生的原因和错误的发展趋势,可以帮助项目管理者发现当前软件开发过程中的缺陷,以便即时改进;
2. 检测产品是否符合用户要求;
3. 没有发现错误的测试也是有价值的,完整的测试是评定软件质量的一种方法;
4. 提升用户体验。
#### 2.2.2 测试的原则
1. 软件测试是证伪而非证实;
2. 尽早地、不断地进行测试;
3. 重视无效数据和非预期的测试;
4. 应当对每一个测试结果做全面的检查;
5. 测试现场保护和资料归档;
6. 程序员应避免检查自己的程序;
7. 充分注意测试中的集群现象;
8. 用例要定期评审,适时补充修改用例。
### 2.3 测试分类
#### 2.3.1 按照测试阶段划分
1. 单元测试
2. 集成测试
3. 确认测试
4. 系统测试
5. 验收测试
软件测试阶段对照表:
| 测试阶段 | 主要依据 | 参与人员/测试方式 | 主要测试内容 |
| -------- | ---------------------------- | ------------------------------ | ---------------------------------------------------------------------------------- |
| 单元测试 | 《详细设计》 | 开发小组执行白盒测试 | 规范、逻辑、路径 |
| 集成测试 | 《概要设计》
《需求文档》 | 开发小组执行白盒测试、黑盒测试 | 接口、路径、功能、性能 |
| 系统测试 | 《需求文档》 | 独立测试小组执行黑盒测试 | 功能测试、界面测试、安全测试、兼容性测试、易用性测试、性能测试、压力测试、负载测试 |
| 验收测试 | 《需求文档》 | 用户执行黑盒测试 | 同上 |
#### 2.3.2 按照执行状态划分
1. 静态测试
2. 动态测试
#### 2.3.3 按照测试技术划分
1. 白盒测试
2. 黑盒测试
3. 灰盒测试
#### 2.3.4 按照执行主体划分
1. α测试
2. β测试
3. 第三方测试
#### 2.3.5 按照测试内容划分
1. 界面测试
2. 功能测试
3. 安全测试
4. 兼容性测试
5. 易用性测试
6. 性能测试
#### 2.3.6 按照是否手工操作划分
1. 手工测试
2. 自动化测试
### 2.4 测试用例
#### 2.4.1 简介
测试用例是指对一项特定的软件产品进行测试任务的描述,体现测试方案、方法、技术和策略。其内容包括:测试目标、测试环境、输入数据、测试步骤、预期结果、测试脚本等,最终形成文档。
简单的认为,测试用例是为某个特定目标而编制的一组测试输入、执行条件和预期结果,用于核实是否满足某个特定的软件需求。
选择测试用例是软件测试员最重要的一项任务,不正确的选择可能导致测试量过大或者过小,甚至测试目标不对。准确评估风险,把无穷尽的可能性减少到可以控制的范围是软件测试成功的诀窍。
#### 2.4.2 测试用例的作用
1. 指导测试的实施;
2. 评估测试结果的度量基准;
3. 保证软件的可维护性和可复用性;
4. 分析缺陷的标准。
#### 2.4.3 测试用例设计准则
1. 有效性
2. 经济性
3. 完备性
4. 可判定性
5. 可再现性
#### 2.4.4 测试用例维护
**术语**
1. 测试编号:测试用例的编号
2. 测试项:测试的功能点说明
3. 前置条件:该测试用例的前提条件,比如测试wangdachui/dachui12345(用户名/密码)账户是否能正确登录进去,那前提wangdachui/dachui12345一定是注册过的
4. 测试步骤:就是测试的所有操作步骤,最好是每一个步骤应该对应一个期望结果,最少也得一个测试用例对应一个期望结果
5. 期望结果:就是希望得到的结果(正确的结果)
6. 测试结果:实际测试的结果,可选项有:通过、不通过、暂时挂起/锁定(就是暂时不测试)
7. 对应的bug:当期望结果与实际结果不符时测试不通过,此时需要上报bug(记录缺陷),bug需要与测试用例对应
8. 测试执行人:实际由谁来执行测试用例;也有任务分配人的选项,就是测试用例分配给哪个测试员来测试
9. 备注:做一些备注或者测试的说明
10. 合法用户:就是已经注册过的用户
11. 非法用户:没有注册过;注册过但是用户名/密码不匹配的;本文特指未注册过的用户
测试用例维护一般分为以下几种情况:
1. 产品特性没变:漏测或者环境变更,这个时候版本没变,测试用例增加和修改均可;
2. 原有特性变化:功能变化,只能新增,不能修改,还要兼容老版本;
3. 原有功能取消:测试用例在新版本上置为“空”标志或者“无效状态”,对于先前版本有效;
4. 新增功能:新增用例,对应新版本标志。
#### 2.4.5 测试用例设计误区
1. 测试用例设计等同于测试输入数据设计;
2. 测试用例设计越详细越好;
3. 追求测试用例设计“一步到位”;
4. 将多个测试条件混在一个用例中。
### 2.5 测试停止标准
#### 2.5.1 软件测试停止总体标准
1. 测试超过了预定时间;
2. 执行了所有的测试用例,并没有发现故障;
3. 使用特定的测试用例设计方法作为判断测试停止的基础;
4. 给出测试停止的要求;
5. 根据单位时间内查出故障的数量决定是否停止测试;
6. 软件系统经过了单元、集成、系统测试,分别达到停止标准。通过验收测试,得出验收测试结论;
7. 软件项目暂停以进行调整,测试应随之暂停,并备份暂停点数据。或者软件项目开发生命周期内出现重大估算、进度偏差,需暂停或终止时,测试应随之暂停或终止,并备份数据。ß
#### 2.5.2 软件测试各阶段停止标准
##### 单元测试停止标准
1. 单元测试用例已经通过评审;
2. 按照单元测试计划完成了所有规定单元测试;
3. 达到了测试计划中关于单元测试所规定的覆盖率要求;
4. 被测试的单元每千行代码必须发现至少3个错误;
5. 软件单元功能与设计一致;
6. 单元测试中发现的错误已经得到修改,各级缺陷修复率达到标准。
##### 集成测试停止标准
1. 集成测试用例已经通过评审;
2. 按照集成测试计划和增量集成策略完成了整个系统的集成测试;
3. 达到了测试计划中关于集成测试所规定的覆盖率要求;
4. 被测试的集成工作版本每千行代码必须发现至少2个错误;
5. 集成工作版本满足设计定义的各项功能、性能要求;
6. 在集成测试中发现的错误已经得到修改,各级缺陷修复率达到标准。
##### 系统测试停止标准
1. 系统测试用例已经通过评审;
2. 按照系统测试计划完成了系统测试;
3. 达到了测试计划中关于系统测试所规定的覆盖率要求;
4. 被测试的系统每千行代码必须发现至少1个错误;
5. 系统测试满足设计需求规格说明书要求;
6. 在系统测试中发现的错误已经得到修改,各级缺陷修复率达到标准。
### 2.6 知识点总结
1. 软件测试的目的和原则
2. 软件测试的分类(测试阶段、执行状态、测试技术、执行主体)
3. 测试用例设计和维护
4. 测试停止标准
## 第3章 黑盒测试
### 3.1 概述
黑盒测试也称功能测试,通过测试来检测每个功能是否都能正常使用。
着眼于程序外部结构,不考虑内部逻辑结构,通过测试检验每个功能是否能正常使用。在程序接口进行测试,只检查程序功能是否能按照需求规格说明书的规定正常使用,程序是否能适当的接受输入数据而产生正确的输出信息。
黑盒测试从用户的角度出发,以输入数据与输出数据的对应关系进行测试,数据驱动。
黑盒测试注重测试软件的功能需求,主要视图发现下列几类错误
1. 功能不正确或遗漏;
2. 界面错误;
3. 数据库访问错误;
4. 性能错误;
5. 初始化和终值错误。
### 3.2 等价类划分
等价类是指某个输入域的子集合。在该子集合中,测试某等价类的代表值就等于对这类其他值的测试,对于揭露程序的错误是等效的。
**要注意的是,在进行等价类划分的过程中,我们不仅要考虑有效等价类划分,也要考虑无效等价类划分。**
有效等价类:是指输入完全符合程序规格说明的数据集合。利用有效等价类可以测试程序是否满足规格说明书规定的功能和性能。
无效等价类:和有效等价类相反,是指对程序的规格说明无意义、不合理的输入数据构成的集合。
#### 3.2.1 划分原则
1. 在输入条件规定了取值范围的情况下,可以确立一个有效等价类(在取值范围之内)和两个无效等价类(小于取值范围和大于取值范围);
2. 在输入条件规定了取回个数的情况下,可以确立一个有效等价类(在取值个数范围之内)和两个无效等价类(小于取值个数和大于取值个数);
3. 在输入条件规定了输入值的集合的情况下,可以确立一个有效等价类和一个无效等价类;
4. 在输入条件规定了“必须如何”条件的情况下,可以确立一个有效等价类和一个无效等价类;
5. 在输入条件是一个布尔值的情况下,可以确立一个有效等价类和一个无效等价类;
6. 在规定了输入数据的一组值(假定n个),并且程序要对每一个输入值分别处理的情况下,可以确立n个有效等价类和一个无效等价类;
7. 在规定了输入数据必须遵守规则的情况下,可以确立一个有效等价类(符合规则)和若干个无效等价类(从不同角度违反规则);
8. 在确知已划分的等价类中各元素在程序处理中的方式不同的情况下,则应再将改等价类进一步划分为更小的等价类。
#### 3.2.2 设计测试用例步骤
1. 形成等价类表,每一等价类规定一个唯一编号;
2. 设计测试用例,使其尽可能多的覆盖尚未覆盖的有效等价类;
3. 设计一个新的测试用例,使其只覆盖一个无效等价类,重复这一步直到所有无效等价类均被覆盖。
#### 3.2.3 等价类举例
我们要测试学习成绩这一输入框(假设总成绩都是100),那么我们就可以如下图划分,有效的成绩是>=0且<=100的,无效的是<0和>100这两部分。

另外图中还有一个无效等价类没有表现出来--非数字字符(比如:英文字母、中文、特殊的符号等单一或者组合,如a、abc、你好、你abc、你=我、\你\a\等;以及他们分别与数字组合,比如:a123、321a、你123、12你、1你2、1\2、1=你等)。
那么根据上述分析,最终设计出来的测试用例如下:
1. 有效等价类1:0~100(包含0和100)之间的任意数,比如:19;
2. 无效等价类1:小于0的负数,比如:-1;
3. 无效等价类2:大于100的数,比如:121;
4. 无效等价类3:其他任意非数字字符,比如:a、你、\;
5. 无效等价类4:空字符。
**等价类最终必须是分割到最小单位,只有这样才能保障测试覆盖全面。**
非数字字符可以是包含英文字符、中文、特殊符号的字符串或者字符,所以其实它又可以分为三个无效等价类,分别是:
1. 无效等价类:包含英文字符的字符串,比如:a、a123、a=、b你a;
2. 无效等价类:包含中文的字符串,比如:你、你12、1你2、你=;
3. 无效等价类:包含特殊字符的字符串,比如:\ 。
### 3.3 边界值分析
边界值分析法是等价类划分法的补充。顾名思义,边界值分析法是对输入的边界值进行测试。从实践中我们可以发现,人们无论是在生活中还是在工作中往往会忽略边界值的条件,所以在输入或者输出的边界上会发生大量的错误。因此,在测试用例设计中,需要对输入的条件进行分析并且提取其中的边界值条件,通过对这些边界值的测试来查出更多的错误。
常见的边界值:
1. 文本框接受字符个数,比如用户名长度、密码长度等;
2. 报表的第1行和最后1行;
3. 数组元素的第1个和最后1个;
4. 循环的第1次、第2次和倒数第1次、最后1次。
#### 3.3.1 设计原则
1. 如果输入条件规定了值的范围,则应取刚达到这个范围边界的值,以及刚刚超越这个范围边界的值作为测试输入数据;
2. 如果输入条件规定了值的个数,则用最大个数、最小个数、比最小个数少1、比最大个数多1的数作为测试数据;
3. 如果规格说明书给出的输入域或输出域是有序集合,则应选取集合的第1个元素和最后1个元素作为测试用例;
4. 如果程序中使用了内部数据结构,则应选择内部数据结构边界上的值作为测试用例;
5. 分析规格说明,找出其他可能的边界条件。
#### 3.3.2 两类方法
1. 一般边界值分析
对于含有n个变量的程序,取值为min、min+、normal,max-、max,测试用例数目为4*N+1。

2. 健壮性边界值分析
健壮性边界值测试是边界值分析的一种扩展。变量除了取min、min+、normal、max-、max 5个边界值外,还要考虑略超过最大值(max+)以及略小于最小值(min-)的取值。因此,对于含有n个变量的程序,健壮性边界值分析产生6*n+1个测试用例。

#### 3.3.3 应用举例
延伸上节的例子来说明:学生信息系统中有一个“考试成绩”的输入项,成绩的取值范围是0~100之间的整数,考试成绩及格的分数线是60,优秀的分数线是80。那么这个例子中的边界值数据是哪些呢?
> 选取的边界值数据应该包括:
>
> -1、0、1、59、60、61、79、80、81、99、100、101
通常情况下,软件测试所包含的边界检验有以下几种类型:数字、字符、位置、质量、大小、速度、方位、尺寸、空间等,而相应地,这些类型的边界值应该在最大/最小,首位/末尾,上/下,最快/最慢,最高/最低,最短/最长,空/满等情况下。
| 测试项 | 边界值 | 测试用例设计思路 |
| :----: | ---------------------------------- | ---------------------------------------------------------------- |
| 数字 | 起始位数-1
结束位数+1 | 成绩,正确0-100,边界-1,0,100,101 |
| 字符 | 起始-1个字符
结束+1个字符 | 用户名输入框,正确1-32位,边界0、1、32、33,注意中文字符占位不同 |
| 方向 | 刚差一点
刚超一点 | 游戏,通过门口,边界值门内一步和门外一步 |
| 空间 | 小于空余空间一点
大于满空间一点 | 磁盘剩余20G,边界19.9G和20.1G |
| 位置 | 上下左右里面一点
外面一点 | 按钮,四边内四点,外四点 |
#### 3.3.4 局限性
如果被测程序是多个独立变量的函数,这些变量受物理量的限制,则较适合采用边界值分析。这里的关键是 **“独立”的“物理量”** 。例如,Date是3个变量(年、月、日)的函数,对其采用边界分析测试用例,就会发现测试用例是不充分的,例如,没强调2月和闰年。其存在问题是因为没有考虑月份、日期和年变量之间存在的依赖关系。由于边界值分析假设变量是完全独立的,因此边界值分析测试用例是对物理量的边界独立导出变量极值,不考虑函数的性质,也不考虑变量的语义含义。
边界值分析对布尔变量和逻辑变量没有多大意义。例如,布尔变量的极值是true和false,但是其余3个值不明确。
### 3.4 决策表
等价类划分法和边界值分析法只是孤立地考虑各个输入数据的测试效果,没有考虑输入数据的组合及其相互制约关系,而决策表考虑了多种条件的组合情况。决策表又称为判定表,分析多种逻辑条件(if-else、switch-case等)与执行之间的关系。
决策表由4部分组成:
1. 条件桩:列出了问题的所有条件,通常认为列出的条件次序无关紧要;
2. 动作桩:列出了问题规定可能采取的操作,这些操作的排列顺序没有约束;
3. 条件项:列出针对条件桩的取值,在所有可能情况下的真假值;
4. 动作项:列出在条件项的各种取值情况下应该采取的动作。
规则:任何条件组合的特定取值及其相应要执行的操作。在决策表中贯穿条件项和动作项的列就是规则。显然,决策表中列出多少条件取值,也就有多少规则,条件项和动作项就有多少列。

所有条件都是逻辑结果(即真/假、是/否、0/1)的决策表称为有限条件决策表。如果条件有多个值,则对应的决策表叫做扩展条目决策表。决策表设计测试用例,条件解释为输入,动作解释为输出。
决策表适合以下特征的应用程序:
1. if-then-else分支逻辑突出;
2. 输入变量之间存在逻辑关系;
3. 涉及输入变量子集的计算;
4. 输入和输出之间存在因果关系;
5. 很高的圈复杂度。
#### 3.4.1 应用举例
决策表(判定表)设计测试用例的具体步骤如下:
1. 确定规则的个数。假如有n个条件,每个条件有两个取值(0,1),故有2种规则;
2. 列出所有的条件桩和动作桩;
3. 填入条件项;
4. 填入动作项,得到初始判定表;
5. 简化,合并相似规则(相同动作);
简化就是合并多条具有相同的动作的规则,并且其条件项之间存在极为相似的关系。

需求:输入三边值,判定是哪种三角形:非三角形、不等边三角形、等腰三角形、等边三角形
1. 绘制初始三角形判定决策表;
2. 优化1的产出;
3. 设计测试用例。
条件桩:
* abc能构成三角形
- a+b>c
- a+c>b
- b+c>a
* a=b?
* a=c?
* b=c?
动作桩:
* 非三角形
* 不等边三角形
* 等腰三角形
* 等边三角形
决策表:
| | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| ------------ | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| a+b>c? | N | Y | Y | Y | Y | Y | Y | Y |
| a+c>b? | | N | Y | Y | Y | Y | Y | Y |
| b+c>a? | | | N | Y | Y | Y | Y | Y |
| a=b? | | | | Y | Y | N | N | N |
| a=c? | | | | Y | N | Y | N | N |
| b=c? | | | | | | | Y | N |
| 非三角形 | √ | √ | √ | | | | |
| 不等边三角形 | | | | | | | | √ |
| 等腰三角形 | | | | | √ | √ | √ | |
| 等边三角形 | | | | √ | | | | |
测试用例:
| 用例ID | a | b | c | 预期输出 |
| :----: | --- | --- | --- | ------------ |
| TC1 | 1 | 2 | 4 | 非三角形 |
| TC2 | 1 | 4 | 2 | 非三角形 |
| TC3 | 4 | 2 | 1 | 非三角形 |
| TC4 | 3 | 3 | 3 | 等边三角形 |
| TC5 | 3 | 3 | 4 | 等腰三角形 |
| TC6 | 3 | 4 | 3 | 等腰三角形 |
| TC7 | 4 | 3 | 3 | 等腰三角形 |
| TC8 | 3 | 4 | 5 | 不等边三角形 |
#### 3.4.2 优点和缺点
决策表把复杂问题的各种可能情况一一列出,易于理解。但是,决策表不能表达重复执行动作的缺点。
使用判定表设计测试用例的条件如下:
1. 规格说明以判定表形式给出,或很容易转换成判定表;
2. 条件的排列顺序不会也不影响执行哪些操作;
3. 规则的排列顺序不会也不影响执行哪些操作;
4. 每当某一规则的条件已经满足,并确定要执行的操作后,不必检验别的规则;
5. 如果某一规则得到满足要执行多个操作,这些操作的执行顺序无关紧要。
这5个必要条件使得操作的执行完全依赖于条件的组合。对于不满足条件的判定表,可增加其他的测试用例。
### 3.5 因果图
前面我们介绍的等价类划分法和边界值分析法都没有考虑到输入情况的组合。这样虽然各种输入条件可能出错的情况已经看到了,但是多个输入情况组合起来可能出错的情况却被忽视了
>地铁自动充值机充值
>
>假设自动充值机每次只能投入面值50或者面值100的人民币,投入钱后会有充值50和充值100两个选项
等价类划分法和边界值分析法可能不会测试到投入面值50的人民币,然后点击充值100这种异常情况;因此,当程序的输入条件有多个的话,就需要用到因果图法来设计测试用例了。
因果图利用图解法分析输入的各种组合情况,适合描述多种输入条件的组合、相应产生多个动作的方法。因果图法最终生成的是判定表。
#### 3.5.1 基本术语
1. 原因结果图:
原因——结果图使用了简单的逻辑符号,以直线连接左右结点,左结点表示输入状态(原因),右结点表示输出状态(结果)。

* “恒等”:若原因出现,则结果出现;若原因不出现,则结果不出现。
* “非”:若原因出现,则结果不出现;若原因不出现,则结果出现。
* “或”:若几个原因中有一个出现,则结果出现;若几个原因都不出现,则结果不出现。
* “与”:若几个原因都出现,结果才出现;若其中有一个原因不出现,则结果不出现。
2. 约束图:
输入输出状态相互之间存在的某些依赖关系,称为约束。

* E(互斥):原因不会同时成立,最多1个成立,可以都不成立。
* I(包含):原因中至少一个成立,不能同时为0。
* O(唯一):原因中有且只有一个成立。
* R(要求):原因中a出现,b必须出现,a=1则b=1,a=0的话,b随便。QQ登录的例子a为自动登录,b是记住密码。
* M(屏蔽):a为1时,b必须是0,a=1,则b=0,如果a=0,b随便。
#### 3.5.2 设计因果图测试用例步骤
1. 分析软件规格说明,哪些是原因(即输入条件或输入条件的等价类),哪些是结果(即输出条件),给每个原因和结果赋予标识符;
2. 分析原因与结果之间、原因与原因之间对应的逻辑关系,用因果图表示;
3. 由于语法或环境限制,有些原因与原因之间、原因与结果之间的组合情况不可能出现,在因果图上用一些记号表明这些特殊情况的约束或限制条件,把因果图转换为判定表;
4. 从判定表的每一列产生出测试用例。
对于逻辑结构复杂的软件,先用因果图进行图形分析,再用判定表进行统计,最后设计测试用例。当然,对于比较简单的测试对象,可以忽略因果图,直接使用决策表。
#### 3.5.3 应用举例
需求:第一列字符必须是A或者B,第二列为数字,才允许进行文件修改。如果第一列字符不正确,输出提示L,第二列不是数字,输出提示M,采用因果图设计测试用例
原因:
1. 第一列是A
2. 第一列是B
3. 第二列是数字
结果:
1. 修改文件
2. 输出提示L
3. 输出提示M
因果图:

决策表:
| | 1 | 2 | 3 | 4 | 5 | 6 |
| -------- | :---: | :---: | :---: | :---: | :---: | :---: |
| A | 1 | 1 | 0 | 0 | 0 | 0 |
| B | 0 | 0 | 1 | 1 | 0 | 0 |
| 数字 | 1 | 0 | 1 | 0 | 1 | 0 |
| 修改文件 | 1 | 0 | 1 | 0 | 0 | 0 |
| 提示L | 0 | 0 | 0 | 0 | 1 | 1 |
| 提示M | 0 | 1 | 0 | 1 | 0 | 1 |
测试用例:
| 用例ID | 第一列 | 第二列 | 预期输出 |
| :----: | :------: | :------: | -------- |
| TC1 | A | 1 | 修改文件 |
| TC2 | A | C、汉、# | 提示M |
| TC3 | B | 2 | 修改文件 |
| TC4 | B | D、字、! | 提示M |
| TC5 | E、符、% | 3 | 提示L |
| TC6 | F、特、@ | G、殊、* | 提示L和M |
#### 3.5.4 优点和缺点
**优点:**
1. 考虑多个输入之间的相互组合、相互制约的关系;
2. 指出需求规格说明书中存在的不完整性和二义性;
3. 帮助测试人员按照一定的步骤高效的开发测试用例。
**缺点:**
1. 作为输入条件的原因和输出结果之间的因果关系,很难从规格说明书得到;
2. 此方法得到的用例数量规模大。
### 3.6 场景法
通过运用场景来描述业务流程(业务逻辑),设计用例来遍历场景(路径),验证系统功能的正确性。
场景法重点是测试流程,因此每个流程用一个用例验证即可,流程测试没问题不代表系统功能没问题,还需要单步进行测试,结合前面的方法。
流程图:
* 矩形:步骤
* 菱形:判断条件
* 箭头:流向
#### 3.6.1 ATM取款流程图

#### 3.6.2 ATM取款场景设计
| 场景编号 | 流程 | 结果 |
| :------: | ---------------------------------------------------------------------------------------- | -------------------- |
| 1 | 插入合法的卡
输入正确的密码
ATM有现金
输入正确的金额
余额充足
ATM现金充足 | 成功提款 |
| 2 | 插入不合法的卡 | 提示错误,退卡 |
| 3 | 插入合法的卡
输入密码点取消 | 退卡 |
| 4 | 插入合法的卡
输入错误的密码(还有机会) | 提示错误,重新输入 |
| 5 | 插入合法的卡
输入错误的密码(超出限制次数) | 提示错误,退卡/吞卡 |
| 6 | 插入合法的卡
输入正确的密码
ATM没有现金 | 提款选项不可用,退出 |
| 7 | 插入合法的卡
输入正确的密码
ATM有现金
输入不合法的金额 | 提示错误,重新输入 |
| 8 | 插入合法的卡
输入正确的密码
ATM有现金
输入正确的金额
余额不足 | 提示错误,重新输入 |
| 9 | 插入合法的卡
输入正确的密码
ATM有现金
输入正确的金额
余额充足
ATM现金不足 | 提示错误,重新输入 |
#### 3.6.3 测试用例
| 用例ID | 场景/条件 | 卡片 | 密码 | ATM内金额 | 账户余额 | 输入金额 | 预期结果 |
| :----: | ------------------------------- | ------ | ------ | --------: | -------: | -------: | ------------------------ |
| TC1 | 场景1:成功提款 | 合法卡 | 123456 | 2000.00 | 5000.00 | 100 | 成功提款,账户余额400.00 |
| TC2 | 场景2:非法的卡 | 非法卡 | n/a | 2000.00 | 5000.00 | n/a | 提示错误,退卡 |
| TC3 | 场景3:点取消 | 合法卡 | n/a | 2000.00 | 5000.00 | n/a | 退卡 |
| TC4 | 场景4:密码错误(还有机会) | 合法卡 | 654321 | 2000.00 | 5000.00 | n/a | 提示错误,重新输入 |
| TC5 | 场景5:密码错误(超过限制次数) | 合法卡 | 234516 | 2000.00 | 5000.00 | n/a | 提示错误,退卡/吞卡 |
| TC6 | 场景6:ATM无现金 | 合法卡 | 123456 | 0.00 | 5000.00 | n/a | 提款选项不可用,用例结束 |
| TC7 | 场景7:金额错误 | 合法卡 | 123456 | 2000.00 | 5000.00 | 20 | 提示错误,重新输入 |
| TC8 | 场景8:卡内余额不足 | 合法卡 | 123456 | 2000.00 | 5000.00 | 600 | 提示错误,重新输入 |
| TC9 | 场景9:ATM现金不足 | 合法卡 | 123456 | 2000.00 | 5000.00 | 2500 | 提示错误,重新输入 |
### 3.7 错误推测法
#### 3.7.1 概念
错误推测法是利用经验和直觉推测出出错的可能类型,列举出程序中所有可能的错误和容易发生错误情况的清单,根据清单设计测试用例。所谓凭经验,是指人们对过去所作测试结果的分析,对所揭示缺陷的规律性直觉的推测来发现缺陷。
该方法强调的是对被测试软件的需求理解以及设计实现的细节把握,当然还有个人的能力。那么显而易见地,这个方法的缺点就是太过依赖个人能力,难以系统化。因此,这个方法一般是作为测试用例设计的补充,而不是单独用来设计测试用例。在回归测试中应用较多。
错误推测法一般采用如下技术:
1. 有关软件设计方法和实现技术;
2. 有关前期测试阶段结果的知识;
3. 测试类似或相关系统的经验,了解以前这些系统曾在哪些地方出现缺陷;
4. 典型的产生错误的知识,如被零除错误。
#### 3.7.2 优点和缺点
**优点:**
1. 不用设计等价类的测试用例,将多个等价类的测试合成一个随机测试,可以以较少代码实现测试代码的编写;
2. 当等价类设计不确切或不完全时,测试会产生遗漏,而使用错误推测法则是按照概率进行等价类覆盖。不论存在多少个等价类,只要随机数据个数足够,就能保证各个等价类被覆盖的概率足够高,能够有效弥补等价类分法设计不充分的缺陷;
3. 采用错误推测法进行测试,每次执行测试时,测试的样本数据可能都不相同,执行次数愈多,错误暴露的概率愈大。
**缺点:**
1. 错误推测法中的随机数据很难覆盖到边界值,无法保证测试的充分性;
2. 错误推测法进行自动化测试的难度较大。有些程序很难用程序来自动验证,这使得程序结果的验证工作难度变大;
3. 当等价类的范围较小,这些范围较小的等价类被覆盖的概率也是很小的,错误推测法难以测试到;
4. 随机测试不可以代替常规的功能或非功能测试,因为其随意性大,没有一套完整严格的方法且并非有章可循的测试技术。
#### 3.7.3 常见错误
1. 页面规范相关部分(跟公司甚至项目需求有关系)
- 命名、注释、字体、颜色、缩进等
- 文本框长度/范围限制
- 支持的浏览器、操作系统、jdk等做兼容性测试
2. 常识性问题
- 密码用密文
- 手机号码是11位,且是特定三位数开头
- 文本框自动忽略前后空格
- 支持模糊查询
3. 常见的异常测试情况
- 输入框不输入任何内容(为空)或者输入空格的情况
- 输入框输入非法字符
- 用户注销后,是否仍然能操作;再登录是否能成功
- 断电重连后是否能继续使用且信息未丢失
4. 功能相关的常见异常问题
- C++软件的内存泄漏、内存分配
- web程序的session失效问题
- JavaScript字符转义
### 3.8 综合策略
黑盒测试方法有等价类划分、边界值分析、决策表、因果图、场景法、错误推测法等,每种测试方法都有其各自的特点和适用场合。
软件测试专家Myers给出了黑盒测试方法中各种测试方法的使用策略:
1. 在任何情况下都必须使用边界值分析方法。经验表明,用这种方法设计的测试用例发现程序错误的能力最强;
2. 必要时使用等价类划分方法补充一些测试用例;
3. 用错误推测法再追加一些测试用例;
4. 对照程序逻辑,检查已设计出的测试用例的逻辑覆盖程度,如果没有达到要求的覆盖标准,应当再补充足够的测试用例;
5. 如果程序的功能说明中含有输入条件的组合情况,则一开始就可选用因果图法。
对于功能性测试技术,可以根据如下条件进行选择:
1. 如果变量是独立的,则可以用定义域测试和等价类测试;
2. 如果变量不是独立的,可采用决策表测试;
3. 如果为单缺陷假设,则可采用边界值分析和健壮性测试;
4. 如果为多缺陷假设,可采用最坏情况测试、健壮最坏情况测试和决策表测试;
5. 如果程序包含大量例外处理,可采用健壮性测试和决策表测试;
6. 如果变量引用的是逻辑量,可采用等价类测试用例和决策表测试。
### 3.9 知识点总结
1. 等价类划分
2. 边界值分析
3. 决策表
4. 因果图
5. 场景法
6. 错误推测法
7. 综合策略
## 第4章 白盒测试
### 4.1 概述
白盒测试是把测试对象看做打开的盒子,允许测试人员利用程序内部的逻辑结构及有关信息设计或选择测试用例,通过在不同点检查程序状态确定实际状态是否与预期的状态一致。白盒测试测试软件产品的内部结构和处理过程,而不测试软件产品的功能,用于纠正软件系统在描述、表示和规格上的错误,是进一步测试的前提。
白盒测试分为静态测试和动态测试。
静态白盒测试是在不执行的条件下有条理地仔细审查软件设计、体系结构和代码,从而找出软件缺陷的过程,有时也称为结构分析。
动态白盒测试也称结构化测试,通过查看并使用代码的内部结构设计和执行测试。
*白盒测试发展史*
1. 单步调试、半手工、没有统一规范的评判标准;
2. 脚本测试,可评估;
3. 规范记录、解决了重复测试的问题;
4. 测试过程融入软件的整个开发全过程,解决了持续测试问题。
### 4.2 静态测试
静态方法是指不运行被测程序本身,仅通过分析或检查源程序的语法、结构、过程、接口等来检查程序的正确性。对需求规格说明书、软件设计说明书、源程序做结构分析、流程图分析、符号执行来找错。
此类过程中应用数据较少,主要过程为通过软件的静态性测试(即人工推断或计算机辅助测试)测试程序中运算方式、算法的正确性,进而完成测试过程,此类测试的优点在于能够消耗较短时间、较少资源完成对软件、软件代码的测试,能够较为明显地发现此类代码中出现的错误。静态测试方法适用范围较大,尤其适用于较大型的软件测试。
静态测试有代码检查、静态结构分析。
* 代码检查
主要是检查代码的可读性、逻辑表达的正确性、结构的合理性等方面。一般在编译和动态测试之前执行,具有走查、审查或伙伴检查等方法
* 静态结构分析
测试者通过使用测试工具,分析程序代码数据结构等控制逻辑,生成函数调用关系图等,用于检查函数之间的调用关系是否符合要求,是否存在递归调用,函数的调用是否过深,是否存在孤立的函数,用于检测系统是否存在结构缺陷。
### 4.3 动态测试
动态测试方法是指通过运行被测程序,检查运行结果与预期结果的差异,并分析运行效率、正确性和健壮性等性能。主要目的为检测软件运行中出现的问题,较静态测试方式相比,其被称为动态的原因即为其测试方式主要依赖程序的运用,主要为检测软件中动态行为是否缺失、软件运行效果是否良好。
### 4.4 逻辑覆盖
逻辑测试,又称为控制流覆盖,是一种按照程序内部逻辑结构和编码结构设计测试用例的测试方法。目的是要测试程序中的语句,判定(控制流能够分解为不同路径的程序点),条件(形成判定的原子谓词)等。根据覆盖的标准不同,分为语句覆盖、判定覆盖、条件覆盖、条件判定覆盖、修正条件判定覆盖、增强条件判定覆盖、条件组合覆盖和路径覆盖等标准。

#### 4.4.1 语句覆盖
语句覆盖又称为线覆盖面或段覆盖面。其含义是指设计若干个测试用例,使被测试程序中的每一条可执行语句至少被执行1次。
只统计可执行的代码行,不包括:头文件、注释、空行。语句覆盖通常被称为“最弱的覆盖”,由于不考虑各个分支的组合,不能发现判断中逻辑运算符的错误。
测试用例越少越好。
语句覆盖率 = 被测试到的语句数量 / 可执行的语句总数 * 100%
语句覆盖测试方法仅仪针对程序逻辑中的显式语句,无法测试隐藏条件,例子中的第一个逻辑运算符And误写成or,测试用例a=2,b=2,c=4仍能达到语句覆盖的要求,但是并未发现程序中的误写错误。
| 测试用例ID | 测试用例 | a>0 and b>0 | a>1 or c>1 | 执行路径 |
| :--------: | ------------- | :---------: | :--------: | --------- |
| TC1 | a=2, b=2, c=4 | T | T | Ⅰ→Ⅱ→Ⅲ→Ⅳ→Ⅴ |
#### 4.4.2 判定覆盖
判定覆盖(Decision Coverage,DC),又称为分支覆盖或所有边覆盖,测试控制结构中布示表达式分别为真和假(例如if语句和while语句)。布尔型表达式被认为是一个整你.取值为true或 false,而不考虑内部是否包含“逻辑与”或者“逻排或”等操作符。
判定覆盖的基本思想,是指设计的测试用例使程序中每个判定至少分别取“真”分支和取“假”分支各一次,即判断真很值均被满足。
| 测试用例ID | 测试用例 | a>0 and b>0 | a>1 or c>1 | 执行路径 |
| :--------: | --------------- | :---------: | :--------: | --------- |
| TC1 | a=1, b=1, c=3 | T | T | I→II→III→IV→V |
| TC2 | a=1, b=-2, c=-3 | F | F | I→III→V |
| 测试用例ID | 测试用例 | a>0 and b>0 | a>1 or c>1 | 执行路径 |
| :--------: | -------------- | :---------: | :--------: | -------- |
| TC1 | a=1, b=1, c=-3 | T | F | I→II→III→V |
| TC2 | a=1, b=-2, c=3 | F | T | I→III→IV→V |
作为语句覆盖的超集,判定覆盖比语句覆盖要多几乎一倍的测试路径,当然也就具有比语句覆盖更强的测试能力。同样,判定覆盖也具有和语句覆盖一样的简单性,无须细分每个判定就可以得到测试用例。但是,往往大部分的判定语句是由多个逻辑条件组合而成(如判定语句中包含and、or、case),判定覆盖仅仅判断其整个最终结果,而忽略判定内部的每个条件的取值情况,因此必然会遗漏部分测试路径。
#### 4.4.3 条件覆盖
条件覆盖(Condition Coverage,CC)是设计测试用例,使每个判断中每个条件的可能取值至少满足1次。
条件覆盖设计例4.2的测试用例,针对a>0 and b>0判定条件表达式,a>0取值为“真”,记为T1;a>0取值为“假”,记为F1;b>0取值“真”,记为T2;b>0取值为“假”,记为F2;条件表达式a>1 or c>1,a>1取值为“真”,记为T3;a>1取值为“假”,记为F3;c>1取值为“真”,记为T4;c>1取值为“假”,记为F4,如下表所示:
| 测试用例ID | 测试用例 | 覆盖条件 | 具体取值条件 | 执行路径 |
| :--------: | --------------- | -------------- | :-----------: | -------- |
| TC1 | a=2, b=-1, c=-2 | T1, F2, T3, F4 | a>1, b≤0, c≤1 | I→III→IV→V |
| TC2 | a=-1, b=2, c=3 | F1, T2, F3, T4 | a≤0, b>0, c>1 | I→III→IV→V |
条件覆盖只能保证每个条件有1次为真、1次为假,而不考虑所有的判定结果。上表中的测试用例a=2,b=-1和测试用例a=—1,b=2满足了条件覆盖的测试用例,保证了a>0 and b>0两个条件的可能值(True 和False)至少满足1次。但是,由于测试用例的所有判定结果都是False,并没有满足判定覆盖。所以**条件覆盖不一定包含判定覆盖。**
#### 4.4.4 条件判定覆盖
条件判定覆盖的含义是通过设计足够的测试用例,使得判断条件中的所有条件可能至少执行T次取值,同时所有判断的可能结果至少执行1次。因此,条件判定覆盖的测试用例满足如下条件:
1. 所有条件可能至少执行1次取值。
2. 所有判断的可能结果至少执行1次。
| 测试用例ID | 测试用例 | 覆盖条件 | 具体取值条件 | 执行路径 |
| :--------: | ---------------- | -------------- | :-----------: | --------- |
| TC1 | a=2, b=1, c=5 | T1, T2, T3, T4 | a>1, b>0, c>1 | I→II→III→IV→V |
| TC2 | a=-1, b=-2, c=-3 | F1, F2, F3, F4 | a≤0, b<0, c≤1 | I→III→V |
条件判定覆盖能同时满足判定、条件两种覆盖标准,是判定和条件覆盖设计方法的交集。表面上,条件判定覆盖测试了所有条件的取值,但事实并非如此,往往某些条件掩盖了另一些条件,并没有覆盖所有的True 和False取值的条件组合情况,会遗漏某些条件取值错误的情况,为彻底地检查所有条件的取值,需要分解判定语句中给出的复合条件表达式,形成由多个基本判定嵌套的流程图。这样就可以有效地检查所有的条件是否正确了。
#### 4.4.5 修正条件/判定覆盖
修正条件/判定覆盖(Modified Condrtion/Decision Coverage,MC/DC),修正条件判定覆盖是判定中每个条件的所有可能结果至少出现1次,每个判定本身的所有可能结果也至少出现1次,并且每个条件都显示能单独影响判定结果。
1. 语句覆盖
2. 条件判定覆盖
3. 独立影响:其他条件相同,单一条件改变,结果改变。消除判定中的某些条件被其他条件掩盖的问题。
| 序号 | a>0 | b>0 | a>0 and b>0 |
| :---: | :---: | :---: | :---------: |
| 1 | T | T | T |
| 2 | T | F | F |
| 3 | F | T | F |
| 4 | F | F | F |
(1,3)说明条件a独立影响测试结果,(1,2)说明条件b独立影响测试结果
| 序号 | a>0 | b>0 | a>0 and b>0 |
| :---: | :---: | :---: | :---------: |
| 1 | T | T | T |
| 2 | T | F | F |
| 3 | F | T | F |
| 序号 | a>1 | c>1 | a>1 or c>1 |
| :---: | :---: | :---: | :--------: |
| 1 | T | T | T |
| 2 | T | F | T |
| 3 | F | T | T |
| 4 | F | F | F |
(2,4)说明条件a独立影响测试结果,(3,4)说明条件b独立影响测试结果
| 序号 | a>1 | c>1 | a>1 or c>1 |
| :---: | :---: | :---: | :--------: |
| 2 | T | F | T |
| 3 | F | T | T |
| 4 | F | F | F |
修正条件/判定覆盖继承了语句覆盖准则、条件判定覆盖准则、多重条件覆盖等判定条件,同时加入了新的判定条件。
例如,A or B 误写为 A and B。因为 T and T = T or T,且F and F = F or F,两者所得到的判定结果相同,由此可说明,虽然使用了条件判定覆盖(C/DC)准则来测试语句,一些错误不能检测出来。但如果使用MC/DC方法,就可以发现这样的错误。
MC/DC具有如下优点:
1. 继承了多重条件覆盖的优点;
2. 线性增加了测试用例的数量;
3. 对操作数及非等式条件变化反应敏感;
4. 具有更高的目标码覆盖率。
#### 4.4.6 条件组合覆盖
条件组合覆盖(Multiple Condtion Coverage,MCC)的基本思想是设计测试用例使得判断中每个条件的所有可能至少出现1次,并且每个判断本身的判定结果也至少出现1次,与条件覆盖的差别是条件组合厦盖不是简单地要求每个条件都出现“真”与“假”两种结果,而是要求这些结果的所有可能组合都至少出现1次。
条件组合覆盖是一种相当强的覆盖准则,可以有效地检查各种可能的条件取值组合是否正确。它不但可覆盖所有条件可能取值的组合,还可覆盖所有判断的可取分支,但仍可能会遭漏掉有的路径,测试还不完全。
条件组合覆盖的条件划分:
| 编号 | 覆盖条件取值 | 判定取值 | 具体条件取值 |
| :---: | :----------: | ---------------- | ------------ |
| 1 | T1, T2 | a>0 and b>0 取 Y | a>0, b>0 |
| 2 | T1, F2 | a>0 and b>0 取 N | a>0, b≤0 |
| 3 | F1, T2 | a>0 and b>0 取 N | a≤0, b>0 |
| 4 | F1, F2 | a>0 and b>0 取 N | a≤0, b≤0 |
| 5 | T3, T4 | a>1 or c>1 取 Y | a>1, c>1 |
| 6 | T3, F4 | a>1 or c>1 取 Y | a>1, c≤1 |
| 7 | F3, T4 | a>1 or c>1 取 Y | a≤1, c>1 |
| 8 | F3, F4 | a>1 or c>1 取 N | a≤1, c≤1 |
条件组合覆盖测试用例:
| 测试用例ID | 测试用例 | 覆盖条件 | 覆盖判定 | 覆盖组合 | 执行路径 |
| :--------: | ---------------- | -------------- | -------- | ----------------------------------- | --------- |
| TC1 | a=2, b=1, c=5 | T1, T2, T3, T4 | 编号1,5 | a>0 and b>0 取 Y
a>1 or c>1 取 Y | I→II→III→IV→V |
| TC2 | a=2, b=-1, c=-2 | T1, F2, T3, F4 | 编号2,6 | a>0 and b>0 取 N
a>1 or c>1 取 Y | I→III→IV→V |
| TC3 | a=-1, b=2, c=3 | F1, T2, F3, T4 | 编号4,7 | a>0 and b>0 取 N
a>1 or c>1 取 Y | I→III→IV→V |
| TC4 | a=-1, b=-2, c=-3 | F1, F2, F3, F4 | 编号4,8 | a>0 and b>0 取 N
a>1 or c>1 取 N | I→III→V |
条件组合覆盖准则满足判定覆盖、条件覆盖和判定/条件覆盖准则,但线性地增加了测试用例的数量,却不能保证所有的路径被执行测试,仍有可能有部分路径被遗漏,测试还不够全面。
#### 4.4.7 路径覆盖
相对于其他逻辑覆盖法,路径覆盖的覆盖率最大。但随着程序代码复杂度的增加,测试工作量将指数增长。例如:包含10个if语句的代码,有2^10 = 1024个路径要测试,如果增加一个if,就有2^11 = 2048个路径要测试。
| 测试用例ID | 测试用例 | 执行路径 |
| :--------: | ---------------- | --------- |
| TC1 | a=2, b=1, c=5 | I→II→III→IV→V |
| TC2 | a=1, b=1, c=-3 | I→II→III→V |
| TC3 | a=-1, b=2, c=3 | I→III→IV→V |
| TC4 | a=-1, b=-2, c=-3 | I→III→V |
### 4.5 路径分析
路径覆盖会存在如下的困难:

上图中包含的不同执行路径数达5的20次方条,假定对每一条路径进行测试需要1毫秒,一年工作365 × 24小时,要想把所有路径测试完,需3170年。
测试中做到完全的路径覆盖是无法实现的,为解决这一难题只得把覆盖的路径数压缩到一定限度内。
路径分析测试法,是在程序控制流图的基础上,通过分析控制结构的环路复杂性,导出基本可执行路径集合,设计测试用例的方法。该方法把覆盖的路径数压缩到一定限度内,程序中的循环体最多只执行一次。设计出的测试用例要保证在测试中,程序的每一个可执行语句至少要执行一次。
### 4.6 控制结构测试
#### 4.6.1 条件测试
条件测试是检查程序模块中所包含逻辑条件的测试用例设计方法。
条件的错误类型如下:
1. 布尔操作符错误(遗漏布尔操作符,布尔操作符多余或布尔操作符不正确);
2. 布尔变量错误;
3. 布尔括号错误;
4. 关系操作符错误;
5. 算术表达式错误。
分支测试可能是最简单的条件测试策略,对于复合条件C的真分支、假分支以及C中的每个简单条件,都需要至少执行一次。
域测试(Domain Testing)通过分析程序输入域的数据,从有理表达式中导出3个或4个测试进行测试。
#### 4.6.2 循环测试
假设N是通过循环的最大次数
1. 零次循环:从循环入口直接跳到循环出口
2. 一次循环:只有一次通过循环,用于查找循环初始值方面的错误
3. 两次循环:两次通过循环,用于查找循环初始值方面的错误
4. m次循环:m次通过循环,其中m<n,用于检查多次才暴露的错误
5. 比最大循环数少一次
6. 最大循环数
7. 比最大循环数多一次
#### 4.6.3 Z路径覆盖
路径覆盖是路径覆盖的一个变体。不考虑循环的形式和复杂度,也不考虑实际执行循环体的次数是多少,只考虑通过循环体零次和一次这两种情况,零次循环式指跳过循环体,从循环体的入口直接到循环体的出口。通过一次循环体是指检查循环初始值,根据简化循环的思路,循环要么执行,要么跳过,这和判定分支的效果一样。这样就大大减少了循环的个数,将循环结构简化为选择结构。
### 4.7 数据流测试
#### 4.7.1 变量定义/使用分析
变量定义和使用有如下三种缺陷:
1. 变量被定义,但从来没有使用
2. 使用的变量没定义
3. 变量在使用之前定义了两次
### 4.8 程序插桩
它是借助于往被测程序中插入操作来实现测试目的的方法,即向源程序中添加一些语句,实现对程序语句的执行、变量的变化等情况进行检查。
#### 4.8.1 插桩位置
插桩位置主要解决的是在哪儿插的问题,为此将程序按“块”划分,探针主要插桩在其“路口”的位置,主要考虑以下4种位置:
1. 程序的开始,即程序块的第1个可执行语句之前;
2. for、do、do-while、do until 等循环语句开始、结束处。
3. if、else if、else及end if等条件语句各分支开始、结束处。
4. 函数、过程、子程序调用语句之后,
5. 程序的出口,return、call之后。
#### 4.8.2 插桩策略
插桩策略主要解决的是如何在程序中植入探针的问题,包括植入的位置和方法。主要考虑块探针和分支探针。
1. 块探针设计策略:又称“顺序块”,它是若干个相连顺序语句的序列集合。在程序的执行过程中,它具有线性特征。若该线性块的第一条语句被执行,则整个线性块的语句都执行了。这样仅在线性块的开始或末尾处插入一个探针即可,避免了对每条语句都进行的冗余插装操作。
2. 分支探针策略:所有进行true或false判断的语句。它是统计分支覆盖率的探针测试点。
#### 4.8.3 插桩过程
在被测试的源程序中植入探针函数的桩,即函数的声明。而插桩函数的原型在插桩函数库中定义。在目标文件连接成可执行文件时,则必须连入插桩函数库。探针函数是否被触发,就要依据插桩选择记录文件了,要求不同的覆盖率测试会激活不同的插桩函数。
### 4.9 测试方法综述
### 4.10 知识点总结
1. 白盒测试概念
2. 静态测试
3. 动态测试
4. 逻辑覆盖(语句覆盖、判定覆盖、条件覆盖、条件判定覆盖、修正条件/判定覆盖、条件组合覆盖、路径覆盖)
## 第5章 性能测试
### 5.1 基本概念
### 5.2 性能测试分类
#### 5.2.1 负载测试
#### 5.2.2 压力测试
#### 5.2.3 可靠性测试
#### 5.2.4 数据库测试
#### 5.2.5 安全性测试
#### 5.2.6 兼容性测试
#### 5.2.7 可用性测试
### 5.3 性能测试步骤
### 5.4 Web测试
### 5.5知识点总结
## 第6章 软件测试流程
### 6.1 软件测试流程概述
软件测试流程与软件开发流程类似,也包括测试计划、测试设计、测试开发、测试执行和测试评估几个部分。

1. **测试计划:**根据用户需求报告中关于功能要求和性能指标的规格说明书,定义相应的测试需求告,使得随后所有测试工作都围绕着测试需求来进行。同时适当选择测试内容,合理安非测试人员、测试时间及测试资源等。
2. **测试设计:**测试设计是指将测试计划阶段制定的测试需求分解、细化为若干个可执行的测试过,并为每个测试过程选择适当的测试用例,保证测试结果的有效性。
3. **测试执行:**执行测试开发阶段建立的自动测试过程,并对所发现的缺陷进行跟踪管理。测试执行一般由单元测试、集成测试、系统测试、验收测试以及回归测试等步骤组成。
4. **测试评估:**根据缺陷跟踪报告,对软件的质量和开发团队的工作进度及效率进行评价。
### 6.2 测试需求
测试需求根据市场/产品需求定义、分析文档和相关技术文档,输出《可测试性需求说明书》和《测试规格》等报告。
**参与者:** 产品经理,架构师,项目经理,测试/质量管理员(很多公司把这个统称为QA),开发
需求文档检查:
从需求的完整性、明确性、必要性、可测性、一致性、可修改性和优先级出发。
1. 测试需求说明书是否满足了用户提出的每一项要求,实现需求的完整性
2. 检查需求文档的用词、用语问题,实现需求的明确性
3. 检查需求规格说明书对需求覆盖是否正确,实现需求的必要性
4. 软件使用环境的描述是否清晰,实现文档的完整性
5. 需求编号是否正确,实现文档的可修改性
6. 需求是否相互矛盾,实现需求的一致性
7. 检查软件系统允许的输入和预期的输出,实现需求的可测试性
8. 软件系统的性能需求有没有得到清晰地描述,实现需求的完整性
9. 需求的关注重点和实现的先后顺序是否清晰地被描述出来,实现需求的优先级
10. 对软件系统的约束条件是否完整的进行描述,实现需求的可测试性
|序号|检查项|检查结果|
|:---:|----|----|
|1|是否覆盖了用户提出的所有需求项|是[ ] 否[ ] NA[ ]|
|2|用词是否清晰,语义是否存在有歧义的地方|是[ ] 否[ ] NA[ ]|
|3|是否清楚的描述了软件系统需要做什么及不做什么|是[ ] 否[ ] NA[ ]|
|4|是否描述了软件使用的目标环境,包括软硬件环境|是[ ] 否[ ] NA[ ]|
|5|是否对需求项进行了合理的编号|是[ ] 否[ ] NA[ ]|
|6|需求项是否前后一致、彼此不冲突|是[ ] 否[ ] NA[ ]|
|7|是否清楚系统的输入、输出格式,以及输入和输出之间的对应关系|是[ ] 否[ ] NA[ ]|
|8|是否清晰地描述了软件系统的性能需求|是[ ] 否[ ] NA[ ]|
|9|需求的优先级是否合理分配|是[ ] 否[ ] NA[ ]|
|10|是否描述了各种约束条件|是[ ] 否[ ] NA[ ]|
### 6.3 测试计划
测试计划以测试需求为基础,分析产品的总体测试策略,输出《产品总体测试策略)等报告。
**参与者:** 测试组长
测试计划规定测试任务、安排人员、预见风险,指导测试,实现测试的目标。
#### 6.3.1 测试计划要点
1. 测试范围
确定各阶段的测试范围、技术约束等,以及测试成功的标准和要达到的目标。
2. 测试策略
开发有效的测试模型,决定黑盒测试和白盒测试、人工测试和自动化测试的比重等。
3. 测试资源
确定测试所需要的时间和资源,对人员、硬件和软件等资源进行组织和分配。
4. 进度安排
分解项目工作结构,并采用时限图、甘特图等方法制定时间/资源表。
5. 风险及对策
测试可能存在的风险分析,对风险进行回避、监控、管理,采用变更管理和控制等。
#### 6.3.2 步骤
1. 了解项目需求,明确测试对象
根据项目组提供的需求说明书、界面原型、开发计划等文档,了解项目需求,明确本次测试的任务。
2. 制定测试策略
测试的策略包括宏观的测试策略和微观的测试策略战术,为了设计出好的测试策略,需要了解软件的结构、功能分布、各模块对用户的重要程度等,从而决定测试的重点、优先次序、测试的覆盖方式等。设计测试用例时,应尽可能用最少的测试用例发现最多的缺陷,尽可能用精简的测试用例覆盖最广泛的状态空间,还要考虑哪些测试用例使用自动化的方式实现,哪些使用人工方式验证等。
3. 确定资源
确定测试所需的人力资源、硬件、软件、工具等资源。
4. 安排测试进度
测试的进度安排需要结合项目的开发计划、产品的整体计划进行考虑,还要考虑测试本身的各项活动进行安排。把测试用例的设计、测试环境的搭建、测试报告的编写等活动列入进度安排表。
5. 估计计划风险
般可能碰到的风险是项目计划变更、测试资源不能及时到位等问题。制定测试计划时应根据项目的实际情况进行评估,并制定出合理、有效的应对策略,对于项目计划的变更,可以考虑建立更加流畅的沟通渠道,让测试人员能及时了解到变更的情况,以及变更的影响,从而可以作出相应的改变。
### 6.4 测试设计
测试设计建立在测试计划书的基础上,根据测试大纲、测试内容及测试的通过准则,将测试需求转换成测试用例的过程,用于描述测试环境、测试执行的范围、层次和用户的使用场景以及测试输入和预期的测试输出等信息,输出《产品或者版本总体测试方案》等报告。
#### 6.4.1 测试设计内容
1. 制定测试的技术方案,确认各个测试阶段采用的测试技术、测试环境和平台,以及选择什么样的测试工具。其中,系统测试中的安全性、可靠性、稳定性、有效性等是测试技术方案的内容重点。
2. 设计测试用例,根据产品需求分析、系统设计等规格说明书,在测试技术方案的基础上设计具体的测试用例。
3. 根据测试的目的和任务,以及测试用例的特性和属性(优先级、层次、模块等)设计测试用例,从而构成执行某个特定测试任务的测试用例集合(组),如基本测试用例组、专用测试用例组、性能测试用例组、其他测试用例组等。
4. 根据所选择的测试工具,将自动化测试的测试用例转换为测试脚本。
5. 根据所选择的测试平台以及测试用例所要求的特定环境,进行服务器、网络等测试环境的设计。
软件测试设计中,需要考虑如下要点。
1. 所设计的测试技术方案是否可行、是否有效、是否能达到预期的测试目标;
2. 所设计的测试用例是否完整、边界条件是否考虑、其覆盖率能达到的百分比;
3. 所设计的测试环境是否和用户的实际使用环境比较接近。
#### 6.4.2 测试用例属性
设计测试用例主要根据测试用例的以下属性,并结合测试用例的编号、标题、描述(条件、步骤、期望结果)等进行测试用例管理。
1. 优先级
测试用例的优先级越高,被执行的时间越早、执行的频率越多。由最高优先级的测试用例组来构成基本验证测试,每次构建软件包时,都要被执行一遍。
2. 目标性
根据不同的目标设计测试用例。有的测试用例是为主要功能而设计,有的则为系统的负载而设计。
3. 所属范围
根据测试用例所属不同的组件或模块进行管理。
4. 关联性
测试用例一般和软件产品特性相联系,多数情况下验证某个产品的功能。
5. 阶段性
根据不同的测试阶段,如单元测试、集成测试、系统测试、验收测试等设计测试用例,便于得出该阶段的测试覆盖率。
6. 状态性
测试用例有不同的状态,只有被激活的测试用例才被运行。
7. 时效性
针对同样功能,可能所用的测试用例不同,是因为不同的产品版本在产品功能、特性等方面的要求不同。
8. 所有者
测试用例还包括由谁、在什么时间创建,又由谁、在什么时间修改等。
### 6.5 测试执行
#### 6.5.1 单元测试
单元测试即为将整个软件分解为各个单元,随后对单元进行测试。此类测试策略的优点在于所需分析数据较少,且针对性较强,程序开发者于开发过程中可通过操作经验明确出现问题的大致区域,随后针对此类问题对相关单元展开分析,进行问题排查。但需注意的是,某些程序中无具体单元驱动程序,即单个单元无法有效驱动,易出现问题,若针对此类软件展开测试,需重点注意此类分解单元。
单元测试是对软件组成单元进行测试。其目的是检验软件基本组成单位的正确性。测试的对象是软件设计的最小单位:模块。
* 测试阶段:编码后
* 测试对象:最小模块(函数、类、模块)
* 测试人员:白盒测试工程师或开发工程师
* 测试依据:代码和注释+详细设计文档
* 测试方法:白盒测试
* 测试内容:模块接口测试、局部数据结构测试、路径测试、错误处理测试、边界测试
单元测试针对模块进行测试,主要有一下5个任务:
* 模块接口:全局量定义一致性,调用参数
* 局部数据结构:数据的定义和使用
* 边界条件:循环边界和输入边界
* 执行路径:关键路径和重要路径
* 错误处理:非合理输入和系统错误
#### 6.5.2 集成测试
集成测试与单元测试相反,原理为将部分需测试部分作为整体进行集成,随后针对此类集成部分进行测试。测试要求为此类被测试集成题应具有一定的结构,且属于非渐增方式集成。对于较大软件而言,集成测试方式较单元测试方式而言较为繁琐,多数大型软件的测试皆采取渐增方式进行测试。渐增测试方式为集成测试方式的衍生,其能够按照不同次序对软件进行测试,日常测试中,常将两类方式进行集成测试,随后按照次序展开选择。
集成测试也称联合测试、组装测试,将程序模块采用适当的集成策略组装起来,对系统的接口及集成后的功能进行正确性检测的测试工作。主要目的是检查软件单位之间的接口是否正确。
* 测试阶段:一般单元测试之后进行
* 测试对象:模块间的接口
* 测试人员:白盒测试工程师或开发工程师
* 测试依据:单元测试的模块+概要设计文档
* 测试方法:黑盒测试与白盒测试相结合
* 测试内容:模块之间数据传输、模块之间功能冲突、模块组装功能正确性、全局数据结构、单模块缺陷对系统的影响
集成测试的主要任务是解决以下5个问题:
1. 将各模块连接起来,检查模块相互调用时,数据经过接口是否丢失;
2. 将各个子功能组合起来,检查能否达到预期要求的各项功能;
3. 一个模块的功能是否会对另一个模块的功能产生不利的影响;
4. 全局数据结构是否有问题,会不会被异常修改;
5. 单个模块的误差积累起来,是否被放大,从而达到不可接受的程度。
集成测试主要测试软件的结构问题,因此测试建立在模块接口上,多为黑盒测试,适当辅以白盒测试,在集成测试过程中,尤其要注意关键模块测试,关键模块一般具有如下一个或多个特征:同时对应几条需求功能;具有高层控制功能;复杂且易出错;有特殊的性能要求。
集成测试的主要目的是验证组成软件系统各模块的接口和交互作用,分为非增量式集成和增量式集成等。
1. 非增量式测试方法
非增量式测试方法又名大棒集成方法,采用一步到位的方法来测试,将所有模块按程序结构图连接起来,当作整体进行测试。非增量式测试是集中一次进行测试,虽然可能发现很多错误,但为每个错误定位和纠正非常困难,并且在改正一个错误的同时又可能引入新的错误,从而更难断定出错的原因和位置。因此,非增量式集成测试只能适合在规模较小的应用系统中使用。
2. 增量式测试方法
增量式测试方法是指测试从一个模块开始,测试成功后,再添加一个模块进行测试,如此进行。增量式测试采用逐步集成和逐步测试的方法,其测试范围是逐步增大,从而易手错误的定位和纠正。因此,增量式集成测试比非增量式集成测试有比较明显的优越性。
增量式测试方法具有自顶向下、自底向上以及三明治集成测试方法。
增量式测试方法的比较:
|名称|自顶向下增量式|自底向上增量式|三明治集成|
|----|:----:|:----:|:----:|
|集成|早|早|早|
|基本程序工作时间|早|晚|早|
|需要驱动程序|否|是|是|
|需要桩程序|是|否|是|
|工作并行性|低|中|中|
|特殊路径测试|难|容易|中等|
|计划与控制|难|容易|难|
1. 自顶向下测试是逐步求精,让测试者了解系统的框架,但需要提供驱动模块。由于驱动模块可能不能反映真实情祝,因此测试可能具有不充分性。
2. 自底向上测试采用驱动模块模拟了所有调用,但是需要等到只有最后一个模块加入才能知道整个系统的框架。
3. 三明治集成测试采用自顶向下、自底向上的结合方式,并采取持续集成策略,有助于尽早发现缺陷,提高工作效率。
#### 6.5.3 系统测试
一般情况下,系统测试采用黑盒法来进行测试的,以此来检查该系统是否符合软件需求。本阶段的主要测试内容包括健壮性测试、性能测试、功能测试、安装或反安装测试、用户界面测试、压力测试、可靠性及安全性测试等。为了有效保证这一阶段测试的客观性,必须由独立的测试小组来进行相关的系统测试。另外,系统测试过程较为复杂,由于在系统测试阶段不断变更需求造成功能的删除或增加,从而使程序不断出现相应的更改,而程序在更改后可能会出现新的问题,或者原本没有问题的功能由于更改导致出现问题。所以,测试人员必须进行回归测试。
将软件系统看成是一个系统的测试。包括对功能、性能以及软件所运行的软硬件环境进行测试。时间大部分在系统测试执行阶段。
* 测试阶段:集成测试通过之后
* 测试对象:整个系统(软、硬件)
* 测试人员:黑盒测试工程师
* 测试依据:需求规格说明文档
* 测试方法:黑盒测试
* 测试内容:功能、界面、可靠性、易用性、性能、兼容性、安全性等
#### 6.5.4 验收测试
验收测试是最后一个阶段的测试操作,在软件产品投入正式运行前的所要进行的测试工作。和系统测试相比而言,验收测试与之的区别就只是测试人员不同,验收测试则是由用户来执行这一操作的。验收测试的主要目标是为向用户展示所开发出来的软件符合预定的要求和有关标准,并验证软件实际工作的有效性和可靠性,确保用户能用该软件顺利完成既定的任务和功能。通过了验收测试,该产品就可进行发布。
但是,在实际交付给用户之后,开发人员是无法预测该软件用户在实际运用过程中是如何使用该程序的,所以从用户的角度出发,测试人员还应进行α测试或β测试这两种情形的测试。α测试是在软件开发环境下由用户进行的测试,或者模拟实际操作环境进而进行的测试。α测试主要是对软件产品的功能、局域化、界面、可使用性以及性能等等方面进行评价。而β测试是在实际环境中由多个用户对其进行测试,并将在测试过程中发现的错误有效反馈给软件开发者。所以在测试过程中用户必须定期将所遇到的问题反馈给开发者。
验收测试是部署软件之前的最后一个测试操作。它是技术测试的最后一个阶段,也称为交付测试。验收测试的目的是确保软件准备就绪,按照项目合同、任务书、双方约定的验收依据文档,向软件购买都展示该软件系统满足原始需求。
* 测试阶段:系统测试通过之后
* 测试对象:整个系统(包括软硬件)。
* 测试人员:主要是最终用户或者需求方。
* 测试依据:用户需求、验收标准
* 测试方法:黑盒测试
* 测试内容:同系统测试(功能...各类文档等)
#### 6.5.5 α测试
软件交付使用之后,用户在使用过程中常常会发生各种问题,如操作使用方法的误解、异常的数据组合等。α测试和β测试用于发现可能只有最终用户才能发现的错误。
α测试是在开发环境或公司内部用户在模拟实际操作的环境下,由用户参与的测试,主要用于评价软件产品的功能、可靠性、性能等,特别是对于软件界面和易用性进行测试。
α测试不能由程序员或测试员完成。
#### 6.5.6 β测试
只有当α测试达到一定的可靠程度时,才能开始β测试。与α测试不同,开发者通常不在测试现场,在β测试中,由用户记下遇到的所有缺陷,向开发者报告。测试着重于产品的支持性测试,包括文档、客户培训等。
α测试与β测试的区别:
1. 测试的场所不同:α测试是指把用户请到开发方的场所来测试,β测试是指在一个或多个用户的场所进行的测试。
2. 测试的环境不同:α测试的环境是受开发方控制的,用户的数量相对比较少,时间比较集中。β测试的环境是不受开发方控制的,用户数量相对比较多,时间不集中。
3. 测试的时间不同:α测试先于β测试执行。通用的软件产品需要较大规模的β测试,测试周期比较长。
当软件通过最后阶段的测试 - 验收测试或质量全面评估测试,从研发阶段来看,工程发布(Engineering Release,ER)将作为一个里程碑,随后将软件推向市场。进行α测试后,到达了有限可用(Limited Available,LA)里程碑(LA是指由于测试覆盖率不能达到100%,软件功能并不能全部使用)。LA之后所发现的缺陷,再通过β测试,到达全面可用(General Available,GA)里程碑,此时所有功能可以全部使用。
### 6.6 回归测试
微软测试表明,一般修复3~4个错误会产生一个新的错误,新代码的加入,除了本身含有错误外,还有可能对原有的代码带来影响。因此,软件一旦发生变化,必须重新设计测试用例,检测软件功能,确定修改达到预期目的。回归测试是一种验证已变更系统的完整性与正确性的测试技术,用于确保修改没有带来副作用。回归测试输出《产品或版本测试报告》等报告。
**这里要注意的是我们bug修订后不只要重新测试这个bug,还要重新测试与这个功能点甚至是代码块相关的部分。**
回归测试与一般测试有如下不同:
1. 测试用例来源
一般测试根据系统规格说明书和测试计划进行,测试用例都是新的。而回归测试可能是更改了的规格说明书、修改过的程序和需要更新的测试计划。
2. 测试范围
一般测试目标是检测整个程序的正确性,而回归测试目标是检测被修改的相关部分的正确性以及它与系统原有功能的整合。
3. 时间分配
一般测试所需时间通常是在软件开发之前预算,而回归测试所需的时间(尤其是修正性的回归测试)往往不包含在整个产品进度表中。
4. 开发信息
一般测试可以随时获取关于开发的知识和信息。而回归测试可能会在不同的地点和时间进行,需要保留开发信息,以保证回归测试的正确性。
5. 完成时间
由于回归测试只需测试程序的一部分,完成所需时间通常比一般测试少。
6. 执行频率
回归测试往往要多次进行,一旦系统经过修改就需要进行回归测试。
#### 6.6.1 测试流程
1. 在测试策略制定阶段制定回归测试策略。
2. 确定回归测试版本。
3. 发布回归测试版本,按照回归测试策略执行回归测试。
4. 回归测试通过,关闭缺陷跟踪单。
5. 回归测试不通过,缺陷单返回到开发人员处,等待重新修改,再次作回归测试。
#### 6.6.2 什么情况下需要回归测试
1. 开发修订了bug
影响较小,很容易获悉影响范围,以及回归测试用例的选择。
2. 版本发布
每次版本的发布或者更新,都必须保障原有功能的正确性以及新功能的正确性;因此回归测试的范围必须是全面的。
3. 新功能提测
新上线的功能,我们首先要保障新功能的正确性;另外保障它没有影响与其相关联的功能,即保障其相关功能的正确性。
修订bug和新功能可以只回归相关部分,版本发布需要回归整个产品。
#### 6.6.3 测试用例设计方法
1. 选择全部测试用例
选择完全重复测试,是指将所有的测试用例全部再完全地执行一遍,以确认问题修改的正确性和修改后周边是否受到影响。缺点是由于要把用例全部执行一遍,因此会增加项目成本,也会影响项目进度,所以很难完全执行。
**优点:** 这其实是最安全的方法,再测试全部用例具有最低的遗漏回归错误的风险,它几乎可以应用到任何情况下,且几乎不需要进行分析。
**缺点:** 测试成本极其高昂
**策略:** 定时执行全部回归(自动测试脚本)以及上线前执行。
2. 基于风险选择测试用例
根据缺陷的严重性来进行测试,基于一定的风险标准,从测试用例库中选择回归测试包。选择最重要、关键以及可疑的测试,跪过那些次要的、例外的测试用例或功能相对非常稳定的模块。
3. 基于操作剖面选择测试用例
如果测试用例是基于软件操作面开发的,测试用例的分布情况将反映系统的实际使用情况。回归测试所使用的测试用例个数由测试预算确定,可以优先选择针对最重要或最频繁使用功能的测试用例,尽早发现对可靠性有最大影响的故障。
4. 覆盖修改法
针对发生错误的模块设计测试用例,只能验证本模块是否还存在缺陷,但不能保证周边与它有联系的模块不会因为这次改动而引发缺陷在修改范围内的测试,其效率最高,风险也最大,因为它无法保证这个修改是否影响了别的功能,该方法一般用于软件结构设计的耦合度较小的状态下使用。
5. 周边影响法
除了执行出错模块的用例之外,把周边和它有联系的模块的用例也执行一遍,保证回归测试的质量。
6. 指标达成法
根据一定的覆盖率指标选择回归测试。例如,规定修改范围内的测试是90%,其他范围内的测试阅值为60%,该方法一般是在相关功能影响范围难以界定时使用。
7. 再测试修改部分
通过相依性识别软件的修改情况,将回归测试局限于被改变的模块,只选择相应的测试用例来做回归测试,此策略风险最大,但成本也是最低。
**优点:** 工作量小
**缺点:** 这个方法对测试人员的要求还是很高的,需要测试人员不仅要熟悉业务,还要能看懂代码且了解代码结构。这么来看这个方法风险还是很高的.
**策略:** 要求开发修订bug后在缺陷管理工具上直接标明影响范围,测试只做审核和实施。
### 6.7 测试评估
#### 6.7.1 测试评估活动
1. 审查测试全过程
在测试跟踪的基础上对测试项目进行全过程、全方位的审视,检查测试计划、测试用例是否得到执行,检查测试是否有漏洞。
2. 对当前状态的审查
测试的审核包括软件缺陷和过程中没解决的各类问题。对产品目前存在的缺陷进行逐个分析,了解其对产品质量影响的程度,决定所有测试内容是否完成,测试的覆盖率是否达到要求以及产品质量是否达到标准,从而确定是否停止测试。
#### 6.7.2 缺陷分析方法
1. 缺陷分布分析
缺陷分布分析是横向分析方法,针对一个或多个缺陷属性进行分布分析,生成缺陷数量与缺陷属性的函数。
缺陷分布分析涉及的因素如图:

2. 缺陷趋势分析
缺陷趋势分析用于描述一段时间内缺陷的动态变化情况。其中,收敛趋势图是其中常用的一种。它是指在一定周期内遗留缺陷的变化情况,用于反映项目的质量变化情况,作为产品发布的一个重要参考。

- 发现缺陷:测试人员在某一测试周期内新发现的缺陷总数。
- 修复缺陷:测试人员在某一测试周期内修复的缺陷总数。
- 遗留缺陷:在某一测试试用周期结束时刻未关闭的缺陷总数。
3. 注入矩阵分析
软件缺陷有“注入阶段”和“发现阶段”两个阶段,缺陷注入-发现矩阵如下表:
||需求|设计|编码|注入总计|
|----|----|----|----|----|
|需求阶段|8|||8|
|设计阶段|26|62||88|
|单元测试阶段|4|11|12|27|
|系统测试阶段|4|3|112|119|
|验收测试阶段|0|0|28|28|
|发现总计|42|76|152|270|
|本阶段缺陷移除率|19%|82%|8%||
矩阵的每行表示该阶段或活动发现的各阶段产生的缺陷数;矩阵的每列表示该阶段或活动注入的缺陷泄漏到后续各环节的缺陷数。
表中的参数解释如下:
**缺陷移除率=(本阶段发现的缺陷数/本阶段注入的缺陷数)×100%**
如需求阶段一共注入了21个缺陷,需求评审时只发现了4个,设计过程中发现了13个,编码和单元测试阶段发现了2个,还有2个直到系统测试阶段才被发现。这样,需求阶段的缺陷移除率 4 / 21 * 100% = 19%。它反映的是该活动阶段的缺陷清除能力。
**缺陷泄露率=(下游发现的本阶段缺陷数/本阶段注入的缺陷总数)×100%**
"缺陷泄漏率",即有多少本阶段注入的缺陷没有在本阶段发现而是被泄漏到后阶段环节才被发现。它反映的是本阶段质量控制措施落实的成效。
编码过程的缺陷大部分依赖系统测试发现。很显然,项目开发过程中的单元测试和集成测试活动开展不够深入。我们可以进一步分析这些系统测试出来的测试缺陷,是不是可以被更前端的评审/测试/设计讨论活动所替代。
需求阶段注入的缺陷绝大部分是在设计阶段发现的。这大概是目前国内公司大部分项目的现实,需求不稳定、不明确,很多东西需要在设计过程中才能明确下来。从分析结果也可以看出,在设计评审时,也需要重新审视需求规格说明书,必要时可利用需求追踪矩阵辅助发现上游需求的缺陷。
通过注入矩阵分析,可以看出软件开发各个环节的质量,找到最需要改进的环节,从而有针对性地制定改进措施。实际规划“缺陷注入一发现矩阵”时,可对缺陷的发现活动和注入阶段进行细分或粗分。
### 6.8 知识点总结
1. 测试需求
2. 测试计划
3. 测试设计
4. 测试执行(单元测试、集成测试、系统测试、验收测试、回归测试)
5. 测试评估(缺陷分布分析、缺陷趋势分析、注入矩阵分析)
## 第7章 软件测试自动化
#### 7.1 自动化测试和手工测试
#### 7.2 测试成熟度模型
#### 7.3 自动化测试体系
#### 7.4 测试工具介绍
#### 7.5 知识点总结
## 第8章 软件测试管理
### 8.1 软件测试管理概述
### 8.2 测试过程改进
### 8.3 人力资源
### 8.4 知识点总结