目录1. 语句覆盖 (Statement Coverage)2. 判定覆盖 (Decision Coverage) / 分支覆盖3. 条件覆盖 (Condition Coverage)4. 判定/条件覆盖 (Decision/Condition Coverage)5. 条件组合覆盖 (Multiple Condition Coverage)6. 路径覆盖 (Path Coverage)总结与对比白盒测试的逻辑覆盖法听起来名词很多容易混淆但其实它们就像是“给代码做体检的不同颗粒度”——从粗到细看看你的测试用例到底跑过了代码的哪些角落。为了让你更好地理解我们先设定一段经典的、带有两个判断逻辑的示例代码作为我们的“靶子”。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: a1、C2: b0、C3: a2、C4: x1。接下来我们用这段代码把这 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)。用例1a 2, b 0, x 4- 判定1(真)判定2(真)。用例2a 1, b 1, x 1- 判定1(假)判定2(假)。缺点判定覆盖只看最终结果不看判定内部的条件。比如判定1是假可能是因为a1也可能是因为b!0它没有对内部细节进行充分测试。3. 条件覆盖 (Condition Coverage)目标让判定里面的每一个独立条件都至少取一次“真”和“假”。通俗理解我不管你整个判定是真是假我只要求组成判定的各个小零件C1, C2, C3, C4都分别变过一次红绿灯。用例设计C1:a1(T/F)C2:b0(T/F)C3:a2(T/F)C4:x1(T/F) (注意这里的 x 是经过第一步运算后的 x)用例1a 2, b 0, x 4- C1(T), C2(T), 此时 x2 - C3(T), C4(T)。用例2a 1, b 1, x 1- C1(F), C2(F), 此时 x1 - C3(F), C4(F)。盲区提醒满足了条件覆盖不一定满足判定覆盖如果有个判定是if (A || B)你设计的用例是(AT, BF)和(AF, BT)满足了条件覆盖但整个判定结果都是 True缺少了 False 分支的覆盖。4. 判定/条件覆盖 (Decision/Condition Coverage)目标小孩子才做选择大人全都要。既要满足“判定覆盖”又要满足“条件覆盖”。通俗理解每个路口的左右拐要走一遍且决定拐向的每一个小零件的正反面也要翻一遍。用例设计刚好上面【3. 条件覆盖】中设计的两个用例a2, b0, x4和a1, b1, x1不仅让所有小条件都取了真假同时也让判定1和判定2的整体结果都取了真假。所以这组用例也满足判定/条件覆盖。5. 条件组合覆盖 (Multiple Condition Coverage)目标针对每一个判定内部所有可能的“条件真假组合”都要执行一次。通俗理解穷举法。判定1有两个条件就有 2x24 种组合判定2有两个条件也有 4 种组合。用例设计* 对于判定1 (a1, b0)需要覆盖(T,T), (T,F), (F,T), (F,F)。对于判定2 (a2, x1)需要覆盖(T,T), (T,F), (F,T), (F,F)。你需要设计多个用例确保这 8 种局部组合都被触发过。这是非常强的一种覆盖方式但用例数量会显著增加。6. 路径覆盖 (Path Coverage)目标覆盖程序中所有可能的完整执行路径。通俗理解从起点到终点不管中间怎么绕所有能走通的完整路线都要走一遍。用例设计我们的代码有两个连续的判断相当于两条连续的分岔路因此有 $2 \times 2 4$ 条路径判定1(真) - 判定2(真)判定1(真) - 判定2(假)判定1(假) - 判定2(真)判定1(假) - 判定2(假)特点路径覆盖能发现最深层次的组合错误但如果代码里有循环比如while循环跑 100 次路径数量会爆炸无穷大所以实际中通常会对循环次数进行限制。总结与对比覆盖方法关注焦点覆盖强度缺陷语句覆盖每一行代码弱最基础漏测率极高判定(分支)覆盖T/F 结果较弱忽略了内部复杂的条件组合条件覆盖每个内部条件较弱可能会漏掉判定的某个分支判定/条件覆盖T/F 结果 内部条件中等依然没有覆盖条件的所有组合条件组合覆盖内部条件的各种组合强用例数量多设计成本高路径覆盖完整的执行流最强 (理论上)存在循环时用例数呈指数级爆炸