白盒测试——动态测试——逻辑覆盖法

目录

[1. 语句覆盖 (Statement Coverage)](#1. 语句覆盖 (Statement Coverage))

[2. 判定覆盖 (Decision Coverage) / 分支覆盖](#2. 判定覆盖 (Decision Coverage) / 分支覆盖)

[3. 条件覆盖 (Condition Coverage)](#3. 条件覆盖 (Condition Coverage))

[4. 判定/条件覆盖 (Decision/Condition Coverage)](#4. 判定/条件覆盖 (Decision/Condition Coverage))

[5. 条件组合覆盖 (Multiple Condition Coverage)](#5. 条件组合覆盖 (Multiple Condition Coverage))

[6. 路径覆盖 (Path Coverage)](#6. 路径覆盖 (Path Coverage))

总结与对比

白盒测试的逻辑覆盖法听起来名词很多,容易混淆,但其实它们就像是"给代码做体检的不同颗粒度"------从粗到细,看看你的测试用例到底跑过了代码的哪些角落。

为了让你更好地理解,我们先设定一段经典的、带有两个判断逻辑的示例代码作为我们的"靶子"。

java 复制代码
void testLogic(int a, int b, int x) {
    // 判定 1 (包含条件 C1 和 C2)
    if (a > 1 && b == 0) { 
        x = x / a;  // 语句 1
    }
    
    // 判定 2 (包含条件 C3 和 C4)
    if (a == 2 || x > 1) { 
        x = x + 1;  // 语句 2
    }
}

在这段代码中:

  • 判定 (Decision/Branch): 指的是整个 if 后面的大括号里的判断结果(真或假)。这里有两个判定:判定1判定2

  • 条件 (Condition): 指的是构成判定的最小逻辑单元。这里有四个条件:C1: a>1C2: b==0C3: a==2C4: x>1

接下来,我们用这段代码把这 6 种覆盖法逐一击破。

1. 语句覆盖 (Statement Coverage)

目标: 让程序里每一行可执行的代码,至少都执行一次

  • 通俗理解: 走马观花,每一行代码我都要走到。这是最基础的覆盖,强度最弱。

  • 用例设计: 我们只需要让 判定1判定2 都为真,就能走进大括号里执行语句1和语句2。

    • 用例: a = 2, b = 0, x = 4

    • 执行过程: * 判定1: 2 > 1 且 0 == 0(真),执行 x = 4 / 2 = 2(覆盖了语句1)

      • 判定2: 2 == 2 或 2 > 1(真),执行 x = 2 + 1 = 3(覆盖了语句2)
  • 缺点: 无法发现隐藏在分支(比如条件为假时)里的逻辑错误。

2. 判定覆盖 (Decision Coverage) / 分支覆盖

目标: 让程序里每一个判定(if)的"真 (True)""假 (False)"分支都至少走一次。

  • 通俗理解: 每一个路口的左拐和右拐,我都要走一遍。

  • 用例设计: 需要 判定1 (T, F)判定2 (T, F)

    • 用例1: a = 2, b = 0, x = 4 -> 判定1(真),判定2(真)。

    • 用例2: a = 1, b = 1, x = 1 -> 判定1(假),判定2(假)。

  • 缺点: 判定覆盖只看最终结果,不看判定内部的条件。比如 判定1 是假,可能是因为 a<=1,也可能是因为 b!=0,它没有对内部细节进行充分测试。

3. 条件覆盖 (Condition Coverage)

目标: 让判定里面的每一个独立条件,都至少取一次"真"和"假"。

  • 通俗理解: 我不管你整个判定是真是假,我只要求组成判定的各个小零件(C1, C2, C3, C4)都分别变过一次红绿灯。

  • 用例设计:

    • C1: a>1 (T/F)

    • C2: b==0 (T/F)

    • C3: a==2 (T/F)

    • C4: x>1 (T/F) (注意这里的 x 是经过第一步运算后的 x)

    • 用例1: a = 2, b = 0, x = 4 -> C1(T), C2(T), 此时 x=2 -> C3(T), C4(T)。

    • 用例2: a = 1, b = 1, x = 1 -> C1(F), C2(F), 此时 x=1 -> C3(F), C4(F)。

  • 盲区提醒: 满足了条件覆盖,不一定 满足判定覆盖!如果有个判定是 if (A || B),你设计的用例是 (A=T, B=F)(A=F, B=T),满足了条件覆盖,但整个判定结果都是 True,缺少了 False 分支的覆盖。

4. 判定/条件覆盖 (Decision/Condition Coverage)

目标: 小孩子才做选择,大人全都要。既要满足"判定覆盖",又要满足"条件覆盖"。

  • 通俗理解: 每个路口的左右拐要走一遍,且决定拐向的每一个小零件的正反面也要翻一遍。

  • 用例设计: 刚好上面【3. 条件覆盖】中设计的两个用例 a=2, b=0, x=4a=1, b=1, x=1,不仅让所有小条件都取了真假,同时也让判定1和判定2的整体结果都取了真假。所以这组用例也满足判定/条件覆盖。

5. 条件组合覆盖 (Multiple Condition Coverage)

目标: 针对每一个判定内部,所有可能的"条件真假组合"都要执行一次。

  • 通俗理解: 穷举法。判定1有两个条件,就有 2x2=4 种组合;判定2有两个条件,也有 4 种组合。

  • 用例设计: * 对于 判定1 (a>1, b==0),需要覆盖:(T,T), (T,F), (F,T), (F,F)。

    • 对于 判定2 (a==2, x>1),需要覆盖:(T,T), (T,F), (F,T), (F,F)。

    • 你需要设计多个用例,确保这 8 种局部组合都被触发过。这是非常强的一种覆盖方式,但用例数量会显著增加。

6. 路径覆盖 (Path Coverage)

目标: 覆盖程序中所有可能的完整执行路径

  • 通俗理解: 从起点到终点,不管中间怎么绕,所有能走通的完整路线都要走一遍。

  • 用例设计: 我们的代码有两个连续的判断,相当于两条连续的分岔路,因此有 2 \\times 2 = 4 条路径:

    1. 判定1(真) -> 判定2(真)

    2. 判定1(真) -> 判定2(假)

    3. 判定1(假) -> 判定2(真)

    4. 判定1(假) -> 判定2(假)

  • 特点: 路径覆盖能发现最深层次的组合错误,但如果代码里有循环(比如 while 循环跑 100 次),路径数量会爆炸(无穷大),所以实际中通常会对循环次数进行限制。

总结与对比

覆盖方法 关注焦点 覆盖强度 缺陷
语句覆盖 每一行代码 最基础,漏测率极高
判定(分支)覆盖 T/F 结果 较弱 忽略了内部复杂的条件组合
条件覆盖 每个内部条件 较弱 可能会漏掉判定的某个分支
判定/条件覆盖 T/F 结果 + 内部条件 中等 依然没有覆盖条件的所有组合
条件组合覆盖 内部条件的各种组合 用例数量多,设计成本高
路径覆盖 完整的执行流 最强 (理论上) 存在循环时,用例数呈指数级爆炸
相关推荐
小陈phd2 小时前
多模态大模型学习笔记(四十五)——视觉推理(Visual Reasoning):从观察到逻辑的复杂认知链
人工智能·笔记·学习
Upsy-Daisy2 小时前
IOTA 学习笔记(八):本地启动 IOTA Localnet
笔记·学习
古方路杰出青年2 小时前
学习笔记:语音信号读取与显示——理论分析与技术详解(含代码块)
笔记·学习·语音识别
中屹指纹浏览器2 小时前
2026指纹浏览器缓存机制深挖:HTTP强缓存与协商缓存隐性风控陷阱
经验分享·笔记
Sean_VIP2 小时前
FreeRTOS项目程序框架介绍(五)
笔记·stm32
searchforAI3 小时前
Ai好记 vs Get笔记:AI音视频笔记工具深度测评对比
人工智能·笔记·学习·ai·音视频·语音识别
噜噜噜阿鲁~3 小时前
python学习笔记 | 11.5、面向对象高级编程-使用枚举类
笔记·python·学习
GLDbalala4 小时前
GPU PRO 5 - 2.5 TressFX: Advanced Real-Time Hair Rendering 笔记
笔记
憧憬成为java架构高手的小白4 小时前
数据库期末复习笔记
数据库·笔记·oracle