软件工程 · 第 4 章

第 4 章 编码与测试

测试目的与五条原则;黑盒(等价类、边界值,含 0~100 例题);白盒五种覆盖强弱排序;单元→集成→确认→系统;α/β 测试。

4.1 测试的目的与原则

先掰正一个直觉:测试是为了"发现错误",不是为了"证明没错"。

测试的目的
  • 以发现错误为目的执行程序的过程——找茬,而不是自证清白。
  • 测试只能证明"有错",不能证明"无错"(穷尽测试不可能,输入空间无穷大)。
测试原则(高频)
  • 测试用例必须包含预期输出(没有预期结果就不算完整用例)。
  • 尽早测试——需求阶段的错误越晚发现,修复成本越高(错误修复成本随阶段指数级上升)。
  • 程序员应避免测试自己的程序(思维定势会漏错),由独立测试人员执行更有效。
  • 测试用例要包含合理输入和不合理输入(异常场景往往更能揪出问题)。
  • 发现错误越多的模块,残留错误也越多(错误有"聚集"现象)——重点回归测试。
课堂练习(3 题)
  1. "测试能证明程序没有错误"这句话对吗?为什么? 答:错。测试只能发现错误、证明"有错",无法穷尽所有输入来证明"无错"。
  2. 为什么强调"尽早测试"? 答:错误发现越晚,修复涉及的范围和成本越大;需求/设计阶段的错误在编码后发现代价最高。
  3. 完整的测试用例由什么组成? 答:测试输入 + 预期输出。

4.2 黑盒测试:等价类与边界值

测试阶段与黑白盒测试方法
图 4-1 四阶段测试 + 黑盒(等价类/边界值)与白盒(覆盖强度由弱到强)

不管程序内部怎么写,只看"输入→输出"对不对。设计用例有套路。

黑盒测试(功能测试):把程序当黑箱,依据需求规格设计用例。

方法思路要点
等价类划分把输入域划分成若干"类",每类挑一个代表测试分有效等价类(合法输入)与无效等价类(非法输入)
边界值分析错误最爱藏在边界上取 边界值本身、边界±1(如范围 1~100 → 测 0、1、100、101)
错误推测凭经验猜哪里容易错补充手段
因果图输入条件的组合关系了解名字
例题:给"成绩输入 0~100"设计边界值用例
边界值分析取:-1、0、1、99、100、101
  -1   ← 刚好低于下界(应报错)
   0   ← 下界(有效)
   1   ← 下界+1
  99   ← 上界−1
 100   ← 上界(有效)
 101   ← 刚好高于上界(应报错)

等价类划分:
  有效等价类:0 ≤ 成绩 ≤ 100
  无效等价类:成绩 < 0;成绩 > 100;非数字输入
课堂练习(2 题)
  1. 输入范围是 1~12(月份),用边界值分析至少测哪几个值? 答:0、1、2、11、12、13(边界±1 加上边界本身)。
  2. 等价类划分中"无效等价类"指什么? 答:不满足规格要求的非法输入所构成的类(如越界值、错误格式)。

4.3 白盒测试:覆盖到什么程度

白盒测试看内部逻辑,核心考点是"几种覆盖的强弱排序"。

覆盖要求强度
语句覆盖每条语句至少执行一次最弱
判定(分支)覆盖每个判断的真、假两个分支都走到中等
条件覆盖判断中每个条件的真假都取到中上(不一定强于判定覆盖,但通常更强)
判定/条件覆盖判定与条件同时满足更强
路径覆盖所有可能的执行路径都走到最强(路径爆炸,成本高)
示例程序:
    if (A > 0 && B > 0) { X = 1; }
    else { X = 2; }

语句覆盖:让 A=1,B=1 执行 if 分支 → X=1(覆盖了 X=1 的语句),再补 A=0 → 覆盖 else。
判定覆盖:一次让条件整体为真(A=1,B=1),一次为假(A=0,B=1)。
条件覆盖:要让 A>0、A≤0、B>0、B≤0 各出现一次。
路径覆盖:穿真分支、穿假分支两条路径都走。
易错
  • "语句覆盖最强"——错,它是最弱的;路径覆盖最强。
  • 条件覆盖强在"每个条件",但可能漏掉判定整体取值(结合判定/条件覆盖更完整)。
课堂练习(2 题)
  1. 几种覆盖中哪种最强、哪种最弱? 答:路径覆盖最强;语句覆盖最弱。
  2. 白盒测试依据什么来设计用例? 答:程序的内部逻辑结构(代码/流程图),与黑盒依据需求文档不同。

4.4 测试阶段:从小到大地测

"单元→集成→确认→系统"的顺序与目的。

阶段测什么依据
单元测试单个模块/函数内部详细设计(白盒为主)
集成测试模块组装后的接口与协作概要设计;常用自顶向下/自底向上策略
确认(验收)测试"做出来的东西是不是用户要的"需求规格说明书;用户参与
系统测试与硬件、网络、其它系统整体联测(性能、安全、兼容)系统需求
配套概念
  • α 测试——开发场地内,用户在开发者陪同下试用;β 测试——真实用户在实际环境中独立试用。
  • 回归测试——修改代码后重跑既有用例,确认"没把好的改坏"。
  • 测试与排错(Debug)是两回事:先测出"有问题",再定位并修正。
课堂练习(3 题)
  1. 单元测试主要依据哪份文档? 答:详细设计说明书。
  2. α 测试与 β 测试的区别是什么? 答:α 在开发方场所、开发者参与观察;β 在用户真实环境由用户独立完成。
  3. 修改完一个模块后,重新运行之前通过的测试用例,这叫什么测试? 答:回归测试。