第7章01 软件测试概述

3.1 本章定位

本章建立软件测试的总体框架:测试是什么、测试过程有哪些阶段、测试有哪些分类、测试为什么需要多种策略,以及软件测试的三大核心问题。后续黑盒、白盒、回归、性能测试都是本章框架下的具体方法。

3.2 核心概念

软件测试定义

广义上,软件测试是一种软件正确性、完整性、安全性和质量的检查过程。

​ 静态测试泛指其他的软件缺陷检测(V&V)技术,包括技术评审、程序分析、形式化验证、软件度量

​ 但动态测试才是真正意义上的软件测试

狭义上,软件测试是为了发现错误或缺陷而执行某个程序或软件系统的过程。

重要判断:

  • 测试的目的:证明程序有错,而不是证明程序无错误。
  • 测试没有发现错误,不能说明程序中一定没有错误。

测试用例

执行软件测试首先必须有测试用例,然后根据测试用例运行程序,以发现程序或软件可能存在的潜在错误。

测试用例可以基于需求文档/需求模型、设计文档/设计模型、程序代码,通过手工或自动方式生成。

测试用例是对一项特定软件产品进行测试任务的描述,体现测试方案、方法、技术和策略。简单理解:

测试用例=测试输入+测试预言测试用例 = 测试输入 + 测试预言

课件表述中,测试用例包括一组测试输入、执行条件以及预期结果。

一个完整测试用例通常不只包含输入和预期结果,还可以包括测试目标、测试环境、输入数据、测试步骤、预期结果、测试脚本等内容,并最终形成测试文档。

3.3 软件测试过程 STLC

软件测试过程又称软件测试生命周期(Software Test Life Cycle, STLC),从测试项目计划建立到所有测试结束,一般包括七个阶段。

一般来说包括测试需求分析、测试计划制定、测试设计、测试开发、测试执行、测试结果分析与评估、测试报告生成七个阶段

软件测试过程(STLC)

测试阶段核心目标与主要任务具体包含内容 / 关键点
测试需求分析明确测试要点:弄清楚用户需求及系统运行方式,为后续设计提供基础。针对原始需求列表中的每个需求点,提取我们需要测试的测试要点,并分析对应的测试方案或方法。
测试计划制定统筹全局规划:明确测试方向、资源分配与预期交付物。需要明确7个核心要素:测试目标、测试范围、测试项(如安全测试、性能测试等)、测试策略/手段、需要的辅助工具、测试资源(软硬件及人员)、交付/产出物件(如测试计划、日志、缺陷报告等)。
测试设计确定测试方法:将计划转化为可执行的具体用例和标准。1. 设计测试用例:基于白盒(覆盖准则)或黑盒(等价类、边界值等)方法设计。 2. 设计测试脚本:编写或录制用于自动化工具执行的指令。 3. 测试覆盖准则设计:明确选用何种覆盖准则(语句/控制流/分支等)。
测试开发搭建测试基础:进行实际环境与代码级别的准备工作。建立测试环境、录制或编写测试脚本、开发测试驱动程序 (drivers) 和桩模块 (stubs)、建立外部测试数据集。
测试执行运行并记录:实际运行测试并记录结果。执行测试脚本,记录测试执行的具体情况,包括记录日常日志以及详细的 Bug 统计情况。
测试结果分析 与评估分析与对比:对比期望结果,评估代码和用例的覆盖程度。1. 分析测试用例的覆盖情况(如代码覆盖率)。 2. 分析发现缺陷的情况(缺陷类型、严重性分布、趋势与状态等)。 3. 评估是否达到测试停止或成功标准(充分性评估)。
测试报告生成总结与交付:对测试全过程进行承上启下的迭代总结。生成典型测试报告,人工撰写报告或自动生成测试报告,包含:概述、测试时间与环境、测试过程、功能实现清单、缺陷统计、测试统计情况、测试总结以及测试风险分析。

测试计划制定补充:

  • 测试策略/手段需要明确:基于代码覆盖策略的测试、基于规约的测试,还是基于状态的测试。
  • 辅助工具包括:测试管理工具、测试设计工具、缺陷跟踪工具、数据库工具、性能测试工具等。
  • 交付物一般包括:测试计划、测试环境、测试包、测试日志、缺陷报告等。

测试结果分析与评估补充:

  • 覆盖情况:测试用例覆盖情况、代码覆盖率、语句覆盖率等。
  • 缺陷情况:缺陷类型、缺陷分布、缺陷趋势、缺陷状态。
  • 缺陷状态可按:记录、提交、修改、测试、关闭。
  • 最后评估是否达到测试停止标准或成功标准,本质上属于测试充分性评估。

3.4 软件测试分类

按实施主体分类

软件测试根据由谁来测试分成

类型说明
开发者测试开发者在软件开发过程中进行,包含单元测试、集成测试、系统测试、确认测试、回归测试等
用户测试通常发生在验收测试阶段,在实际或模拟使用环境下完成
第三方测试由独立第三方机构进行,增强客观性

开发者测试细化

开发者测试主要发生在软件开发过程中,包括单元测试、集成测试、系统测试、确认测试、回归测试。

  1. 单元测试:单元测试在最低级别完成,测试软件的最基本单元。

软件单元是软件设计说明中一个可独立测试的元素,是程序中逻辑上独立的部分。

单元测试主要测试 5 个方面:模块接口测试;局部数据结构测试;路径测试;错误处理测试;边界测试。

单元测试充分性要求:

  • 语句覆盖达到 100%;
  • 分支覆盖达到 100%;
  • 错误路径处理达到 100%;
  • 单元的软件特性覆盖;
  • 各种数据特性覆盖。
  1. 集成测试:集成测试又称组装测试或联合测试,是单元测试的多级扩展。它将已经通过单元测试的模块按照设计要求逐步装配成高层功能模块,直到形成完整软件系统。

集成测试方法主要有两种:

  • 一次性组装方式:先分别完成各模块单元测试,再把通过测试的模块一次性组装后测试。
  • 渐增式测试:不是独立测试每个单元,而是把下一个待测单元与已经测试过的单元集合组装起来,边连接边测试。典型方式包括自顶向下和自底向上。
  1. 系统测试:系统测试是为了判断系统是否符合规定而对集成的软硬件系统进行的测试活动。测试对象是完整的、集成的计算机系统,重点是新开发的软件配置项集合。

系统测试过程包括:制定系统测试计划、设计测试用例、实施系统测试、执行系统测试、评估系统测试。

系统测试的核心目的包括验证系统完整性、评估非功能性指标,为验收测试铺路

  1. 确认测试:确认测试是在完成集成测试之后,依据确认测试准则,针对软件需求规格说明进行的测试,用于确认软件系统是否满足规定的功能和性能需求。

  2. 回归测试:回归测试是在软件维护或修改之后,为检测代码修改是否引入新错误而进行的测试。它用于确认修改是否达到预期目的,并检查修改是否破坏原有功能。

回归测试可以发生在任何一个阶段包括单元测试,集成测试和系统测试等

回归测试一般步骤:制定回归测试策略;确定需要回归测试的版本;按策略执行回归测试;测试通过则关闭缺陷跟踪单;测试不通过则返回开发人员修改,再次提交测试。

用户测试补充

用户测试一般发生在验收测试阶段,与开发者在开发环境下测试不同,用户测试在实际使用环境或模拟使用环境下完成。

用户或志愿者通过使用软件来观察或体会:功能正确性;性能;可靠性;安全性等实际情况。

用户测试有时又称 Beta 测试,早期用户经验会反馈给开发者,帮助其在正式发布商业版本前进行最终修改。

第三方测试补充

第三方测试的目的在于保证测试工作的客观性

常见情况:

  • 开发团队测试力量薄弱,委托测试公司完成全部或部分测试;
  • 用户测试力量薄弱,在验收或安装使用过程中委托测试机构代测;
  • 软件产品需要上市许可或面向广泛用户群体时,由权威机构进行测试。

第三方测试可能包括: 需求分析审查、设计审查、代码审查、单元测试、功能测试、性能测试、可恢复性测试、资源消耗测试、并发测试、健壮性测试、安全测试、安装配置测试、可移植性测试、文档测试、最终验收测试等。

按内部结构可见程度分类

类型依据关注点适用
黑盒测试需求规格说明输入与输出、功能行为功能测试、系统测试、验收测试等
白盒测试源代码结构和逻辑语句、分支、条件、路径、数据流单元测试、集成测试等
灰盒测试部分内部结构信息接口、模块边界、数据库写入等集成测试、接口测试

注意:灰盒测试结合内部结构信息和外部行为,但不能简单认为“灰盒测试 = 白盒测试 + 黑盒测试”。

3.5 常见测试类型

课件按照需求类型引出多种测试:

  • 功能性需求:结构测试、功能测试、安全性测试、容错测试等;
  • 质量需求:性能测试、压力测试、兼容性测试、可维护性测试等;
  • 其他需求:标准符合度测试、GUI 测试、字体大小和颜色测试等。

常见的软件测试类型汇总

测试大类细分类型 / 常见方法测试目的与核心概念关键特点与评估指标
结构测试 (白盒测试)控制流测试通过执行程序来检查程序逻辑结构(如语句、判定、条件、路径)。常见准则包括语句覆盖、判定覆盖、条件组合覆盖、路径覆盖等 。
数据流测试面向数据的测试,主要搜索变量的定义与使用位置并检查状态变化 。核心是分析变量的“定义-使用路径”(如 du-PATH, dc-PATH)及覆盖度 。
功能测试 (黑盒测试)功能分解法、等价类划分法、因果图判定表法、边界值分析法基于需求规格说明书,不关注内部结构,重点检测程序是否满足特定的功能性需求 。贯穿软件生命周期各阶段 ;边界值法常用来补充等价划分法 。
性能测试通过自动化工具模拟多种正常、峰值及异常负载条件进行测试 。确保系统在高并发、高吞吐等严苛场景下能稳定且正常地运行 。重点关注:TPS(每秒事务数)、QPS(每秒查询数)、响应时间(RT)、并发用户数、资源利用率等 。
安全性测试渗透测试、模糊测试、漏洞扫描、安全扫描、风险评估等专门寻找可能被外界恶意利用的软件脆弱性(包含设计漏洞与代码漏洞)。渗透测试依赖人员经验且覆盖率有限;模糊测试则介于纯手工与全自动化之间 。
可靠性测试故障注入法、异常值输入法、压力测试法、稳定性测试法等评估软件在“规定的条件”和“规定的时间区间”内完成规定功能的能力强调按照实际使用的“概率分布”随机选择测试输入,对测试环境的覆盖要求非常高 。
兼容性测试测试软硬件之间、操作系统、跨软件及浏览器的兼容性非功能性测试,检查软件与硬件、软件与软件之间能否正常进行交互、协同工作 。包含向前/向后兼容、不同版本兼容、标准规范兼容以及数据共享兼容四种典型情况 。
健壮性测试 (容错测试)针对错误数据、异常情况、非法操作处理等场景的测试非功能性测试,检测软件在面临随机非法输入和刻意制造的异常条件下,能否保持正常工作状态 。考察重点分为三个维度:成熟性(避免异常)、容错性(承受异常)和易恢复性(异常后恢复)。
可用性测试实验室实验、现场观察、问卷表调查、启发式评估针对 GUI 系统的评估,度量用户在与系统交互时的实际体验质量 。核心评估标准:易学性、使用效率、可记忆性、错误频率及严重程度、主观满意度 。

安全性测试补充:

软件漏洞主要来源包括:

  • 设计漏洞:如错误或缺失的访问控制机制、未保护的数据管道等;
  • 代码漏洞:如 C/C++ 中使用 gets() 导致缓冲区溢出、进程间竞争条件等。

安全保障方法还包括:漏洞扫描、安全扫描、安全审计、风险评估、道德入侵、姿势评估等。

可靠性测试补充:

软件可靠性测试就是根据软件结构可靠性、软件寿命以及可靠性试验信息,再利用概率统计方法,对软件可靠性做出的评估

可靠性测试方法:故障注入法,异常值输入法,压力测试法和稳定性测试法

可靠性测试步骤:制定测试计划;测试准备;测试实施;测试分析。

软件可靠性测试不同于一般功能测试:

  • 按实际使用的概率分布随机选择输入数据;
  • 需要准确记录软件运行时间;
  • 输入覆盖要求通常高于普通功能测试;
  • 对使用环境覆盖要求更高,尤其是容错软件、实时嵌入式软件等。

可用性测试补充:

可用性测试不仅评价 GUI 设计,还包括用户对系统功能和信息架构的理解。 可用性问题可以分为:

  • 概念层面:导航、用户定位、UI 一致性;
  • 详细设计层面:GUI 标准、术语、具体交互问题。

3.6 软件测试有效策略

课件强调单一测试技术难以满足所有测试需求,应组合使用:

  • 静态测试与动态测试结合;
  • 黑盒测试与白盒测试结合;
  • 内部测试与外部测试结合;
  • 整体测试与局部测试结合等。

静态与动态测试结合策略

策略维度静态测试动态测试
测试原理检查所有可能的输入,分析所有可能的模拟执行情况。检查特定输入,考察程序的实际执行。
核心优点检查范围广无需执行被测程序适合软件开发早期阶段制品(文档、模型等)测试效率高自动化程度高
主要缺点检测效率低(多数是人工方法)检测精度不高自动化程度低需要执行被测程序,不适合早期缺陷检测,面临测试用例生成、测试预言、测试充分性三大难题

静态测试补充:

静态测试一般不执行被测代码,而是利用软件项目信息、过程信息、制品信息以及相关人员信息来检测软件是否存在缺陷。

典型静态测试包括:技术评审;代码审计;静态分析;软件度量;形式化验证。

动态测试补充:

动态测试通过运行被测程序,检查运行结果与预期结果是否存在差异,以判断是否存在缺陷。动态测试效率和自动化程度较高,但需要测试用例,并面临测试用例生成、测试预言、测试充分性三大难题。

白盒与黑盒测试结合策略

策略维度白盒测试黑盒测试
测试原理检查代码内部结构,确保每段代码(包括每条语句、每个判定分支、每个条件等)都被执行。通过测试来检测每个功能是否都能正常使用;着眼于程序外部结构,完全不考虑内部逻辑结构。
核心优点基于程序结构,可发现结构或逻辑缺陷能做到细粒度深度代码检查,更好保障代码安全性与可信性基于需求规约,可发现行为功能方面的缺陷无需了解内部结构,节省程序理解时间适用于各阶段的测试需求
主要缺点代码量很大时无法穷举遍历所有可能性测试用例生成难度大,无法保障 100% 测试覆盖效率往往不高,自动化难度大若外部特性设计或需求规格说明书本身有缺陷,通常无法发现即使反复测试,也不能保障在任何时候都绝对正确

黑盒与白盒结合的理由:

  • 白盒测试检查内部结构,可针对代码逻辑;
  • 黑盒测试观察外部行为,可发现需求实现问题;
  • 二者结合可以更全面发现缺陷。
  • 课件中还特别提到了一种结合了白盒与黑盒优点的 灰盒测试 (Grey-box test) 。它不仅关注输入输出的正确性,也关注程序内部的逻辑覆盖,在集成测试阶段非常适用,但不能简单地将其理解为“灰盒 = 白盒 + 黑盒” 。

内部与外部测试结合策略

策略维度内部测试外部测试
测试原理由软件开发部门自我组织,在部门内部进行的软件测试。以用户体验为主体的测试方法。
核心优点从开发者角度进行,涵盖所有类型测试范围广、类型丰富、测试充分专业性强、可信性高从用户角度进行,以用户体验为主能客观、具体地反映软件的实际使用效果
主要缺点对用户是黑盒的,用户无法得知真实测试数据及核心技术一些潜在问题(如技术债)一般不会对外公开测试充分性难以保障

内部测试 / 外部测试补充:

  • 内部测试相当于 Alpha 测试,一般由开发部门内部组织。
  • 外部测试也称公测,有时等同于 Beta 测试,由用户、第三方或独立机构参与。
  • 内部测试强调充分性、专业性和可信性;外部测试强调真实用户体验和客观反馈。

局部与整体测试结合策略

策略维度局部测试整体测试
测试原理针对软件局部进行的测试,保障组成软件系统的每个部分没有结构、功能方面的问题。针对软件整体进行的测试,保障软件没有功能性、非功能性方面的问题。
核心优点保障组成软件系统的每个部分得到充分测试作为细粒度测试,能发现隐含的局部缺陷保障各软件之间、软硬件之间的交互与集成得到充分测试能有效发现集成过程中的交互缺陷、兼容性缺陷等
主要缺点不能发现整个软件系统集成之后才暴露的缺陷很难发现组成软件系统局部所隐藏的深层缺陷

3.7 软件测试典型方法

五类软件测试典型方法:

方法主要解决的问题核心关键词
组合测试如何在大量参数组合中选择尽量少但有效的测试用例参数组合、组合爆炸、覆盖
随机测试如何补充计划测试中可能遗漏的场景随机输入、复测、缺陷密集区
蜕变测试预期结果难以直接确定时如何判断程序是否正确蜕变关系 MR、测试预言
演化测试如何自动搜索更优测试用例遗传算法、适应值函数、种群
变异测试如何评价现有测试用例集的质量变异算子、变异体、杀死变异体

3.7.1 组合测试

1. 基本定义

组合测试是一种测试组合的功能性测试方法

组合可以包括:硬件的组合;软件的组合;软件功能的组合;程序输入的组合

组合测试的目的,是测试软件在不同组合环境下是否能够正常运行,是否存在与组合相关的问题。

需要注意:组合测试的测试对象不是单独的零散模块,而是那些已经通过单元测试的模块的组合。


2. 为什么需要组合测试

在大规模软件系统中,影响系统运行的参数可能很多,每个参数的取值也可能很多。

组合测试的核心思想是:从庞大的参数组合空间中,选取尽量少的测试组合,也就是测试用例,以较低成本覆盖各种参数组合对系统的影响。

组合测试目标是:从待测软件的参数组合空间中,选取尽量少的测试组合(也就是测试用例),可以很好的覆盖各种参数组合对软件系统的影响,从而实现科学高效软件测试。

组合测试的核心问题是:如何选择测试组合,生成有效测试用例,实现高质量的测试覆盖和测试效果。

组合测试用例生成时,需要重点考虑以下几个问题:

  1. 生成测试用例的规模:生成的测试用例越少,测试所需成本越低。
  2. 生成测试用例所需时间
  3. 算法结果是否可以重现
  4. 是否支持约束与指定:算法是否能够在用户指定部分测试用例的基础上,继续添加约束,生成符合用户要求的新测试用例集。
  5. 生成规模是否有明确上界

3. 组合数量计算

假设待测软件系统有 kk 个待测参数,第 ii 个参数的取值个数为 n(i)n(i),其中:1ik1 \leq i \leq k

则所有可能的组合总数为:i=1kn(i)\prod_{i=1}^{k} n(i)

如果所有参数的取值个数都相同,即:n(i)=nn(i)=n

则组合总数为:nkn^k

这说明组合数量会随着参数个数和取值个数快速增长,形成组合爆炸问题。


3.7.2 随机测试

1. 基本定义

随机测试是一种黑盒测试

随机测试是一种不要求有书面测试用例、记录期望结果、检查列表、脚本或指令的测试

随机测试主要是对被测软件的一些重要功能、性能等进行复测(retest)

随机测试最好由具有丰富测试经验的熟悉被测软件的测试人员进行测试

在随机测试中,测试人员不查看软件产品内部代码,而是在被测系统中通过随机输入来查看结果。

理论上,每一个被测软件版本都需要执行随机测试,尤其是最后即将发布的版本,更应该重视随机测试。


2. 随机测试人员需要具备的条件

随机测试对测试人员经验要求较高。测试人员应具备以下条件:

  1. 熟悉产品的各项功能和产品逻辑;
  2. 熟悉测试用例;
  3. 完整执行过测试用例;
  4. 熟悉用例测试阶段发现的缺陷及其分布;
  5. 具备一定测试经验,善于发现细微缺陷。

随机测试越依赖经验,测试人员越熟悉被测软件,随机测试越容易发现问题。


3. 随机测试点的选取准则

随机测试不是毫无目标地乱测,而是应重点选择高风险区域。

测试点选取准则包括:

  1. 缺陷比较密集的功能板块:缺陷密集区域往往出现新缺陷的概率更高。
  2. 一次性缺陷或重现率较低缺陷涉及的功能板块:低重现率缺陷通常隐藏较深,不易发现,但可能造成严重后果。
  3. 通过与程序员沟通发现的薄弱模块:测试人员可以根据开发人员反馈,重点测试软件薄弱之处。

3.7.3 蜕变测试

1. 基本定义

蜕变测试是一种特殊的黑盒测试方法。

蜕变测试依据被测软件的领域知识和软件实现方法,建立蜕变关系

MR=MetamorphicRelationMR = Metamorphic Relation

然后利用蜕变关系生成新的测试用例,并通过验证蜕变关系是否被保持来判断测试是否通过。

蜕变关系指:多次执行目标程序时,输入与输出之间期望遵循的关系。

蜕变测试不一定直接判断某一次输出是否绝对正确,而是判断多组输入输出之间是否满足某种应有关系。

蜕变测试常用于解决测试预言困难的问题。当我们很难直接知道某个输入的准确预期输出时,可以通过构造输入输出之间的必要关系来间接判断程序是否正确。


2. MR 的形式化理解

假设程序 PP 主要实现函数 ff 的功能。

设:x1,x2,,xnx_1, x_2, \ldots, x_n

是函数 ffnn 个自变量,对应的输出为:f(x1),f(x2),,f(xn)f(x_1), f(x_2), \ldots, f(x_n)

如果输入之间满足关系式 rr,并且输出之间满足关系式 RR,则:(r,R)(r, R)

称为程序 PP 的一种蜕变关系。

通俗理解:输入之间满足某种关系时,输出之间也应该满足某种对应关系


3. 蜕变测试例子

假设被测程序 PP 用来计算指数函数:f(x)=exf(x)=e^x

根据指数函数性质,可以构造蜕变关系:ex×ex=1e^x \times e^{-x} = 1

如果原始测试用例为:ti=0.3t_i = 0.3

则根据蜕变关系可以得到衍生测试用例:ti=0.3t_i' = -0.3

执行程序后,如果:P(0.3)×P(0.3)=1P(0.3) \times P(-0.3) = 1

成立,则说明满足蜕变关系,测试通过。

如果不成立,则说明程序 PP 中可能存在错误。


3.7.4 演化测试

1. 基本定义

演化测试旨在利用遗传算法,在待测软件的输入空间中进行启发式搜索,以较高效率获得满足测试目标的测试用例

它的特点是:高效性;自动化水平高;可以降低测试成本;可以提高测试质量。

演化测试将测试用例生成任务转化为一个优化问题。

转化的关键在于如何量化地表示测试目标,即根据指定测试目标,设置适应值函数,评估不同测试用例的质量,合理的指导搜索的进行

常见演化测试类型包括:结构性演化测试;功能性演化测试;性能演化测试


3.7.5 变异测试

1. 基本定义

变异测试是一种评估软件测试质量的方法。

其核心思想是:通过故意向程序中植入错误,检验现有测试用例能否发现这些错误。

如果现有测试用例能够发现人为植入的小错误,说明测试用例集质量较高;如果发现不了,则说明测试用例集可能不充分,需要补充新的测试用例。

变异操作是其中主要任务之一。

变异操作主要是利用变异算子生成变异体。

变异算子 mutation operator:定义如何从原程序生成差异很小的新程序的转换规则

变异体 mutant / mutation:对原程序执行变异算子后生成的新程序


2. 变异算子和变异体

变异体通常只与原程序有很小差异,例如:

  • 将算术运算符替换;
  • 将逻辑运算符替换;
  • 将关系运算符替换;
  • 删除语句;
  • 替换变量;
  • 替换常量。

3. 传统变异测试基本过程

传统变异测试过程包括:

  1. 给定被测程序 PP 和测试用例集 TT
  2. 根据被测程序特征设定一系列变异算子;
  3. 在原程序 PP 上执行变异算子,生成大量变异体;
  4. 从大量变异体中识别并排除等价变异体;
  5. 在剩余的非等价变异体上执行测试用例集 TT
  6. 如果测试用例能够检测出所有非等价变异体,则变异测试分析结束
  7. 如果仍有未检测出的变异体,则需要额外设计新的测试用例,并添加到测试用例集 TT 中。

4. 变异测试例子

原程序片段:

if (a && b) c = 1;
else c = 0;

如果将逻辑运算符 && 替换为 ||,会产生变异体:

if (a || b) c = 1;
else c = 0;

要杀死这个变异体,需要满足两个条件:

  1. 测试数据必须使原程序和变异体产生不同的内部状态 例如:
a = 1, b = 0

原程序中:

a && b = 0

变异体中:

a || b = 1

两者会导致不同的 c 值。

  1. 差异必须传播到程序输出,并且被测试检查到 也就是说,仅仅内部状态不同还不够,测试用例还要能观察并判断输出差异。

3.7.6 五种典型方法对比

方法类型定位核心思想主要作用
组合测试功能性测试方法从大量参数组合中选取少量有效组合解决组合爆炸,提高组合覆盖效率
随机测试黑盒测试 / 补充测试根据经验随机输入并观察结果补充计划测试,复测高风险场景
蜕变测试特殊黑盒测试检查多次输入输出之间是否满足 MR缓解测试预言问题
演化测试自动化测试用例生成方法用遗传算法搜索优质测试用例提高测试用例生成效率
变异测试测试质量评估方法人为制造变异体,看测试用例能否杀死评价测试用例集充分性和有效性

3.7.7 易混淆点

易混淆点正确理解
组合测试不是穷举测试它是在组合空间中选择尽量少但有效的测试组合
随机测试不是乱测它依赖测试人员经验,重点关注缺陷密集区、低重现率缺陷和特殊场景
蜕变测试不是直接给出标准答案它通过输入输出之间的蜕变关系判断程序是否可能有错
演化测试不是普通随机生成它使用遗传算法,根据适应值函数不断优化测试用例
变异测试不是为了修复程序它主要用于评价测试用例集能否发现人为植入的小错误
可存活变异体不一定都是真错误可能是测试用例不足,也可能是等价变异体未被识别出来

组合测试解决“组合太多怎么选”,随机测试解决“计划测试之外怎么补”,蜕变测试解决“预期结果难确定怎么判”,演化测试解决“测试用例怎么自动优化生成”,变异测试解决“测试用例质量怎么评价”。

最重要的考试记忆点:

  1. 组合测试:从参数组合空间中选择尽量少的测试组合。
  2. 随机测试:黑盒测试,是基于测试计划测试的重要补充。
  3. 蜕变测试:核心是蜕变关系 MR,用于缓解测试预言问题。
  4. 演化测试:利用遗传算法和适应值函数生成测试用例。
  5. 变异测试:通过变异算子生成变异体,用来评估测试用例集质量。

软件测试典型方法汇总

测试方法核心原理与概念主要特点与测试目的关键执行要素
组合测试 (Combinatorial Test)测试软件在多参数、多功能组合环境下的运行情况 。 功能性测试方法,可以包括硬件的组合,软件的组合,软件功能的组合以及程序输入组合旨在避免暴力穷举,从庞大的参数组合空间中选取尽量少的测试用例,实现科学高效的覆盖 。核心在于如何设计约束、选择最优组合算法,以最低的成本覆盖各种参数组合带来的影响 。
随机测试 (Random Test)一种不要求书面用例、脚本或指令的黑盒测试,测试人员通过随机输入查看结果 。作为基于计划测试的补充,重点对缺陷密集区、特殊场景、并发情况及低重现率缺陷进行复测极度依赖测试人员的产品熟悉度、测试经验以及对过往缺陷分布的掌握 。
蜕变测试 (Metamorphic Test)依据领域知识建立程序的“蜕变关系(MR)”,利用初始用例衍生出新的测试用例 。特殊的黑盒测试通过验证多次执行目标程序时,输入与输出之间是否保持期望的蜕变关系来判断测试是否通过 。关键在于定义准确的蜕变关系(例如 exex=1e^x * e^{-x} = 1),它是解决“测试预言(Test Oracle)”难题的有效方法 。
演化测试 (Evolutionary Test)利用遗传算法,在待测软件的输入空间进行启发式搜索 。将测试用例的生成任务转化为优化问题,具有高效性和高度自动化水平,能显著降低成本 。需要合理设置适应值函数(fitness function),通过选择、杂交、变异等种群繁衍过程不断迭代出高质量用例 。
变异测试 (Mutation Test)通过故意在代码中植入错误(生成变异体),来评估现有测试用例能否发现它们 。专门用于评估和检验软件测试(尤其是测试用例集)的质量 。利用变异算子生成变异体,识别并排除等价变异体后,观察测试用例能否“杀死”非等价变异体,未杀死的需补充新用例 。

3.8 软件测试三个核心问题

  • 测试用例生成(test case generation)
  • 测试预言(test oracle)
  • 测试充分性(test coverage)

这三个问题共同决定测试质量:

核心问题解决什么问题影响
测试用例生成如何设计有效测试输入和测试条件决定测试效果和测试效率
测试预言如何判断实际输出是否正确决定测试结果能否与预期结果比较
测试充分性如何判断测试是否足够决定测试覆盖程度和测试可信性

3.8.1 测试用例生成问题

测试用例(test case)是对一项特定软件产品进行测试任务的描述,体现测试方案、方法、技术和策略。

一个完整测试用例通常包括:测试目标;测试环境;输入数据;测试步骤;预期结果;测试脚本等。最终,测试用例需要形成文档。

简单理解:测试用例=测试输入+执行条件+预期结果测试用例 = 测试输入 + 执行条件 + 预期结果

也可以记为:

测试用例=测试输入+测试预言测试用例 = 测试输入 + 测试预言

其中:

  • 测试输入:用于执行程序的数据或条件;
  • 测试预言:用于判断执行结果是否正确的预期结果或判定依据。

常见测试用例生成方法

课件将常见测试用例生成方法分为黑盒测试、白盒测试两大类。

常见黑盒测试用例生成方法包括:等价类划分法;边界值法;功能图法;错误推测法;因果图法;场景法等。

白盒测试又可以分为基于控制流和基于数据流两类。

​ 基于控制流的测试用例生成:语句覆盖;分支覆盖;条件覆盖;分支条件覆盖;条件组合覆盖;路径覆盖等。

​ 基于数据流的测试用例生成:所有定义使用路径覆盖;所有定义使用清洁路径覆盖等。

测试用例生成还可以根据使用技术分为三类:手工生成,半自动生成,自动生成


3.8.2 测试预言问题

测试预言(test oracle)是指测试的预期结果

在软件测试中,关键步骤是比较:实际测试结果vs.预期结果实际测试结果 \quad vs. \quad 预期结果如果二者不一致,就说明被测程序可能存在错误。

很多情况下,精确的预期结果并不容易获得。于是就产生了测试预言问题。

测试预言问题在自动化测试中普遍存在,因为自动化测试不仅要自动执行输入,还要自动判断输出是否正确。

测试预言不能来自待测试系统自身。

1个测试用例=1个测试输入+1个测试预言1个测试用例 = 1个测试输入 + 1个测试预言

其中:

  • 测试输入:用来执行程序;
  • 测试预言:用来检查测试输入执行后产生结果的正确性。

因此,测试预言是测试用例的一部分。

蜕变测试变异测试是为了解决测试语言问题的两种有效方法

蜕变测试基于蜕变关系,变异测试基于变异算子。


3.8.3 测试充分性问题

测试充分性(test coverage)问题本质上就是测试覆盖率问题。测试覆盖率是测试可信性的重要指标。

实际测试中常见覆盖率主要包括两大类:

  • 需求覆盖率;需求覆盖率(requirement coverage)用于评估测试对需求的覆盖程度。
  • 代码覆盖率:至少被执行了一次的代码条目数占整个代码条目数的百分比。

虽常见的代码覆盖率指标有:语句覆盖率,分支覆盖率,条件覆盖率,路径覆盖率

代码覆盖率最好适度,在条件允许的情况下尽可能高(一味追求高覆盖率可能导致测试用例冗余)

覆盖率类型关注对象要求强度
语句覆盖率可执行语句每条语句至少执行一次最弱
分支覆盖率判定整体结果每个判定 True / False 分支至少各一次较强
条件覆盖率判定中的每个条件每个条件 True / False 至少各一次较强
路径覆盖率程序执行路径基本路径或全路径被覆盖最强但成本最高

3.8.4 三个核心问题之间的关系

完整的软件测试过程可以理解为:

生成测试用例执行测试输入根据测试预言判断结果根据覆盖率评估充分性生成测试用例 \rightarrow 执行测试输入 \rightarrow 根据测试预言判断结果 \rightarrow 根据覆盖率评估充分性

3.8.5 易混淆点

易混淆点错误理解正确理解
测试用例只有输入数据测试用例还包括执行条件、预期结果、测试步骤、脚本等
测试预言测试输入测试预言是预期结果或判断结果正确性的依据
测试预言来源可以直接用被测系统自身不能用待测试系统自身作为 oracle
测试充分性覆盖率越高越好覆盖率要适度,过高可能意味着冗余或忽视重要需求
覆盖率低一定不可接受在路径爆炸等场景下,选择性测试也可能满足需求
语句覆盖覆盖了所有逻辑情况语句覆盖是最弱覆盖率指标,不代表所有分支和条件都被覆盖
分支覆盖等同于条件覆盖分支覆盖看判定整体真假,条件覆盖看每个条件真假
  1. 测试用例生成:黑盒、白盒、手工、半自动、自动。
  2. 测试预言:预期结果;不能来自待测系统自身。
  3. 测试充分性:测试覆盖率问题;常见为需求覆盖率和代码覆盖率。
  4. 代码覆盖率:语句覆盖率、分支覆盖率、条件覆盖率、路径覆盖率。
  5. 覆盖率不是越高越绝对好,也不是低覆盖率一定不可接受,要结合测试目标和资源限制判断。
概念错误理解正确理解
测试目的证明程序无错测试是为了发现错误或缺陷
测试预言测试输入预期结果或判定输出正确性的依据
测试充分性只看路径数量可以从需求、代码、功能等角度看覆盖
白盒测试可以保证发现所有逻辑错误即使 100% 覆盖也不能保证发现所有错误

3.9 本章复习检查题

填空题

  1. 软件测试过程一般包括测试需求分析、测试计划制定、测试设计、测试开发、测试执行、________和________七个阶段。
  2. 软件测试的三个核心问题是________、
  3. 测试预言是测试的________。

选择题

  1. 黑盒测试主要基于:A. 代码结构 B. 需求规格 C. 机器码 D. 调试日志
  2. 下列关于测试的说法正确的是:A. 测试没有发现错误说明程序无错 B. 测试的目的之一是发现错误 C. 测试预言来自被测系统自身 D. 灰盒测试等于白盒加黑盒

判断题

  1. 测试覆盖率低不一定意味着测试充分性一定不可接受。
  2. 黑盒测试可以发现需求文档不完整导致的功能缺失问题。
  3. 测试预言可以直接使用被测系统自身作为唯一依据。

参考答案

  1. 填空:测试结果分析与评估、测试报告生成;测试用例生成、测试预言、测试充分性;预期结果。
  2. 选择:B;B。
  3. 判断:对;对;错。

3.10 第7章01 总复习框架

这一章可以概括为一句话:

软件测试是以测试用例为核心,通过静态/动态、黑盒/白盒、内部/外部、局部/整体等多种策略和方法,对软件全生命周期中的功能、性能、安全、可靠性、兼容性、健壮性、可用性等方面进行缺陷发现和质量评估的活动,其核心问题是测试用例生成、测试预言和测试充分性。


3.11 第7章01 客观题必背清单

A. 填空题重点

  1. 狭义软件测试是为了发现错误或缺陷而执行某个程序或软件系统的过程。
  2. 动态测试才是真正意义上的软件测试。
  3. 软件测试的目的是证明程序有错,而不是证明程序无错误。
  4. 软件测试生命周期 STLC 包括:测试需求分析、测试计划制定、测试设计、测试开发、测试执行、测试结果分析与评估、测试报告生成。
  5. 开发者测试包括:单元测试、集成测试、系统测试、确认测试、回归测试。
  6. 单元测试五方面:模块接口测试、局部数据结构测试、路径测试、错误处理测试、边界测试。
  7. 集成测试又叫组装测试或联合测试。
  8. 集成测试方法包括一次性组装方式和渐增式测试。
  9. 渐增式测试典型方式包括自顶向下和自底向上。
  10. 用户测试一般发生在验收测试阶段,有时称 Beta 测试。
  11. 第三方测试的目的是保证测试工作的客观性。
  12. 结构测试又称白盒测试。
  13. 功能测试又称黑盒测试。
  14. 白盒测试包括控制流测试和数据流测试。
  15. 黑盒测试代表方法包括功能分解法、等价类划分法、因果图判定表法、边界值分析法。
  16. 性能测试指标包括 TPS、QPS、RT、ART、并发用户数、资源利用率。
  17. 安全测试关注漏洞或脆弱性。
  18. 可靠性是在规定条件和规定时间区间完成规定功能的能力。
  19. 兼容性测试是非功能性测试。
  20. 健壮性测试有时等同容错测试。
  21. 可用性标准包括容易学习、使用效率、可记忆性、错误频率和严重程度、主观满意度。
  22. 软件测试三个核心问题:测试用例生成、测试预言、测试充分性。
  23. 1 个测试用例 = 1 个测试输入 + 1 个测试预言。

B. 选择题重点

问法答案方向
哪些属于静态测试?技术评审、代码审计、静态分析、软件度量、形式化验证
哪些属于开发者测试?单元、集成、系统、确认、回归测试
哪些属于白盒测试?控制流测试、数据流测试、语句覆盖、路径覆盖
哪些属于黑盒测试?等价类划分、边界值分析、因果图判定表、功能分解
哪些属于性能指标?TPS、QPS、RT、ART、并发用户数、资源利用率
哪些属于安全测试方法?渗透测试、模糊测试、漏洞扫描、安全审计、风险评估
哪些属于可靠性测试方法?故障注入、异常值输入、压力测试、稳定性测试
哪些属于可用性测试方法?实验室实验、现场观察、问卷表、启发式评估
哪些属于测试有效策略?静态+动态、黑盒+白盒、内部+外部、局部+整体
哪些方法可用于测试预言问题?蜕变测试、变异测试

C. 判断题易错点

说法正误原因
测试的目的是证明程序无错误测试目的是发现错误
测试没有发现错误说明程序一定无错未发现不等于不存在
静态测试不需要执行程序静态测试基于制品分析
动态测试不需要测试用例动态测试首先必须有测试用例
黑盒测试不关注程序内部结构基于规约和外部行为
白盒测试基于源代码内部结构关注控制流、数据流等
100%覆盖率一定说明测试充分高覆盖率可能伴随冗余或忽视需求
低覆盖率一定不可接受特殊场景下选择性测试也可能满足需求
用户测试通常在实际或模拟使用环境下进行与开发环境测试不同
第三方测试强调客观性独立于开发者和用户
兼容性测试前应先确保功能正常功能正常是兼容性测试前提
健壮性测试关注异常输入和非法操作检查容错和恢复能力

3.12 第7章01 主观题可能考法

虽然这章是概述,但也可能出情景型主观题。

情景1:给一个软件项目,让你设计测试过程

答题模板:

  1. 进行测试需求分析,明确需求点和测试要点;
  2. 制定测试计划,明确目标、范围、测试项、策略、工具、资源和交付物;
  3. 进行测试设计,设计测试用例、测试脚本和覆盖准则;
  4. 进行测试开发,搭建环境、编写脚本、准备驱动/桩和测试数据;
  5. 执行测试,记录日志和缺陷;
  6. 分析评估结果,包括覆盖率、缺陷分布、停止/成功标准;
  7. 生成测试报告,总结风险和遗留问题。

情景2:给一个系统需求,让你选择测试类型

答题模板:

  1. 功能是否正确:功能测试 / 黑盒测试;
  2. 内部逻辑是否覆盖:结构测试 / 白盒测试;
  3. 高并发响应是否正常:性能测试;
  4. 是否存在漏洞:安全性测试;
  5. 是否能长期稳定运行:可靠性测试;
  6. 是否适配不同平台:兼容性测试;
  7. 是否能处理非法输入和异常:健壮性测试;
  8. 用户是否容易使用:可用性测试。

情景3:给一个测试资源有限的项目,让你制定测试策略

答题模板:

  1. 静态测试与动态测试结合:早期用评审/静态分析,后期运行测试;
  2. 黑盒测试与白盒测试结合:既看需求功能,也看代码结构;
  3. 内部测试与外部测试结合:先内测保障充分性,再外测获得真实用户反馈;
  4. 局部测试与整体测试结合:先测模块、接口,再测集成系统;
  5. 根据风险优先级选择重点测试项,例如安全、性能、核心业务路径。

情景4:给一个测试用例设计问题,让你分析三大核心难点

答题模板:

  1. 测试用例生成:如何选择合适输入、路径、条件或需求覆盖;
  2. 测试预言:如何确定预期输出,是否能获得可靠 oracle;
  3. 测试充分性:如何评估覆盖程度,如需求覆盖率、代码覆盖率。

3.13 第7章01 最终记忆主线

你可以用下面这条线记住本章:

软件测试首先要明确定义和目的,然后按照 STLC 七阶段执行;测试贯穿全生命周期,由开发者、用户和第三方共同参与;测试类型包括结构、功能、性能、安全、可靠性、兼容性、健壮性和可用性;有效测试需要组合静态/动态、白盒/黑盒、内部/外部、局部/整体策略;典型方法包括组合、随机、蜕变、演化和变异测试;最终围绕测试用例生成、测试预言和测试充分性三个核心问题展开。

第7章01最需要优先背的是:

  1. 软件测试目的:证明程序有错,而不是证明无错
  2. STLC 七阶段
  3. 开发者测试、用户测试、第三方测试
  4. 单元、集成、系统、确认、回归测试的区别
  5. 白盒测试 = 结构测试,黑盒测试 = 功能测试
  6. 常见测试类型及适用场景
  7. 四种有效测试策略组合
  8. 组合测试、随机测试、蜕变测试、演化测试、变异测试的基本思想
  9. 测试用例生成、测试预言、测试充分性三个核心问题