当前位置: 首页 > news >正文

【软考架构】软件测试-白盒测试方法中的几种测试准则(覆盖准则)

白盒测试(又称结构测试、透明盒测试)的核心是基于程序内部逻辑结构设计测试用例,其测试准则(覆盖准则)按“覆盖粒度从粗到细、测试强度从弱到强”排序,核心目标是逐步提高代码逻辑的覆盖程度,发现潜在逻辑漏洞。以下是白盒测试中最常用的6种测试准则,含定义、核心要求、示例与适用场景:

一、基础准则:语句覆盖(Statement Coverage)

1. 定义

又称“行覆盖”,是最基础的白盒测试准则,要求程序中每一条可执行语句(非注释、非空行)都至少被执行一次

2. 核心要求

仅关注“语句是否执行”,不关心条件判断、分支走向,覆盖粒度最粗。

3. 示例(代码片段)
if (A && B) {  // 判定1语句1;      // 可执行语句
}
语句2;          // 可执行语句
  • 满足语句覆盖的测试用例:A=T,B=T
    执行路径:判定1=T → 语句1 → 语句2(所有可执行语句均被覆盖)。
  • 未覆盖场景:若用例为A=F,B=任意,则语句1不会执行,不满足语句覆盖。
4. 特点
  • 优点:简单易实现,无需复杂逻辑分析;
  • 缺点:漏洞发现能力极弱(例如A&&B误写为A||B,语句覆盖无法发现);
  • 适用场景:快速验证代码“是否可运行”,仅作为最低测试标准。

二、基础准则:判定覆盖(Decision Coverage)

1. 定义

又称“分支覆盖”,要求程序中每一个“判定表达式”(如ifforwhile后的布尔表达式)的“真(T)”和“假(F)”两种结果都至少被执行一次

2. 核心要求

关注“判定结果的完整性”,覆盖所有分支走向(如if的“执行分支”和“else分支”)。

3. 示例(沿用上述代码)
  • 满足判定覆盖的测试用例(需2个):
    1. A=T,B=T → 判定1=T → 语句1 → 语句2(覆盖判定“真”);
    2. A=F,B=任意 → 判定1=F → 语句2(覆盖判定“假”)。
  • 覆盖效果:所有分支(执行/不执行语句1)均被覆盖。
4. 特点
  • 优点:比语句覆盖强,能发现分支逻辑错误(如if条件写反);
  • 缺点:未关注判定内部“原子条件”的状态(例如A&&BB=F的情况未测试);
  • 适用场景:需要验证分支逻辑完整性的场景,是最常用的基础覆盖准则。

三、进阶准则:条件覆盖(Condition Coverage)

1. 定义

要求判定表达式中每一个“原子条件”(不可拆分的布尔变量,如AB)的“真(T)”和“假(F)”两种状态都至少被执行一次

2. 核心要求

深入判定内部,覆盖所有原子条件的状态,不遗漏单个条件的异常情况。

3. 示例(沿用if (A && B)代码)
  • 原子条件:A(需覆盖T/F)、B(需覆盖T/F);
  • 满足条件覆盖的测试用例(至少2个):
    1. A=T,B=F → 覆盖A=TB=F(判定1=F);
    2. A=F,B=T → 覆盖A=FB=T(判定1=F);
      (补充用例A=T,B=T可覆盖判定1=T,进一步完善)。
  • 覆盖效果:所有原子条件的T/F状态均被覆盖,比判定覆盖更细致。
4. 特点
  • 优点:能发现单个条件的逻辑错误(如A变量赋值错误);
  • 缺点:可能存在“条件覆盖满足,但判定覆盖未满足”(如上例中两个用例均未覆盖判定1=T);
  • 适用场景:需要验证复杂判定内部条件完整性的场景(如多条件组合的if语句)。

四、进阶准则:判定-条件覆盖(Decision-Condition Coverage)

1. 定义

结合“判定覆盖”和“条件覆盖”的要求,需同时满足:

  1. 每个判定表达式的T/F结果至少覆盖一次;
  2. 每个原子条件的T/F状态至少覆盖一次。
2. 核心要求

既保证分支完整,又保证条件完整,避免单一覆盖的缺陷。

3. 示例(沿用if (A && B)代码)
  • 满足判定-条件覆盖的测试用例(需2-4个):
    1. A=T,B=T → 判定1=T,覆盖A=TB=T
    2. A=T,B=F → 判定1=F,覆盖A=TB=F
    3. A=F,B=T → 判定1=F,覆盖A=FB=T
      (无需A=F,B=F,因条件状态已全部覆盖)。
  • 覆盖效果:同时满足判定覆盖和条件覆盖,无遗漏。
4. 特点
  • 优点:覆盖全面,兼顾分支和条件;
  • 缺点:未考虑“条件组合”的完整性(如A=T+B=TA=T+B=F等组合是否全部覆盖);
  • 适用场景:对代码逻辑严谨性要求较高的场景(如金融、医疗系统)。

五、强准则:条件组合覆盖(Condition Combination Coverage)

1. 定义

又称“多重条件覆盖”,要求判定表达式中所有原子条件的“所有可能组合”都至少被执行一次

2. 核心要求

覆盖所有条件组合的场景,是对判定内部逻辑的最全面覆盖(前提:判定中条件无冗余)。

3. 示例(沿用if (A && B)代码)
  • 原子条件组合(共2²=4种):
    1. A=T,B=T;2. A=T,B=F;3. A=F,B=T;4. A=F,B=F
  • 满足条件组合覆盖的测试用例(需4个):
    每个组合对应一个用例,确保所有组合均被执行。
  • 覆盖效果:覆盖所有条件组合,能发现条件组合导致的逻辑错误(如A&&B误写为A||B)。
4. 特点
  • 优点:覆盖强度极高,几乎能发现判定内部所有逻辑漏洞;
  • 缺点:测试用例数量随条件数指数增长(n个条件需2ⁿ个组合),成本较高;
  • 适用场景:核心模块、关键逻辑(如权限校验、数据计算),需极致覆盖的场景。

六、强准则:路径覆盖(Path Coverage)

1. 定义

要求程序中所有“可执行路径”(从入口到出口的完整执行流程)都至少被执行一次

2. 核心要求

关注“流程完整性”,覆盖所有可能的执行路径(包括循环、分支嵌套的路径)。

3. 示例(含循环的代码片段)
int sum = 0;
for (int i=1; i<=2; i++) {  // 判定2:i<=2(T/F)if (i%2 == 0) {          // 判定3:i%2==0(T/F)sum += i;            // 语句3}
}
语句4;
  • 可执行路径(共3条):
    1. i=1 → 判定2=T → 判定3=F → 循环 → i=2 → 判定2=T → 判定3=T → 语句3 → 循环 → i=3 → 判定2=F → 语句4;
    2. i=1 → 判定2=T → 判定3=F → 循环 → i=2 → 判定2=T → 判定3=F → 循环 → i=3 → 判定2=F → 语句4;
    3. i=1 → 判定2=F → 语句4(循环未执行);
  • 满足路径覆盖的测试用例:需设计用例覆盖上述3条路径(如i初始值分别为1、1(修改判定3逻辑)、3)。
4. 特点
  • 优点:覆盖最强,能发现路径相关的逻辑错误(如循环次数错误、嵌套分支遗漏);
  • 缺点:
    1. 路径数量可能极多(嵌套分支、循环会导致路径爆炸);
    2. 部分路径可能不可达(如逻辑上无法执行的路径);
  • 适用场景:简单程序、核心算法模块(如排序、加密算法),需验证所有流程的正确性。

七、各准则对比总结(表格)

测试准则核心覆盖目标测试强度用例数量适用场景
语句覆盖所有可执行语句最弱最少快速验证代码可运行
判定覆盖所有判定的T/F结果弱-中较少基础分支逻辑验证
条件覆盖所有原子条件的T/F状态中等复杂判定内部条件验证
判定-条件覆盖判定T/F + 条件T/F中-强中等兼顾分支与条件的严谨性验证
条件组合覆盖所有条件的组合场景较多核心模块的判定逻辑极致验证
路径覆盖所有可执行路径最强最多简单程序/核心算法的全流程验证

关键结论

  1. 覆盖准则的“强度”:语句覆盖 < 判定覆盖 < 条件覆盖 < 判定-条件覆盖 < 条件组合覆盖 < 路径覆盖;
  2. 测试成本与强度正相关:强度越高,用例设计、执行成本越高,需在“覆盖完整性”和“测试效率”间平衡;
  3. 实际应用:优先使用“判定覆盖”(基础)或“判定-条件覆盖”(兼顾全面性),核心模块可升级为“条件组合覆盖”,路径覆盖仅用于简单场景。

与判断覆盖相比,条件覆盖增加了对判定条件的测试,确实增加了测试路径

要理解这句话,核心是先明确 判定覆盖条件覆盖 的定义差异,再通过具体例子对比二者的测试目标、覆盖范围,最终看清“条件覆盖增加判定条件测试、拓展测试路径”的本质。

第一步:先厘清两个核心概念

在解读前,先明确两个关键术语(以 if (A && B) 这类判定语句为例):

  • 判定(判定表达式):指整个布尔表达式(如 A && B),最终结果只有「真(执行if内逻辑)」或「假(跳过if)」两种。
  • 条件(原子条件):指判定表达式中不可拆分的单个布尔变量(如 AB),每个条件独立有「真(T)」或「假(F)」两种状态。

第二步:用具体例子拆解差异

我们以一个简单的 if 语句为例,直观对比两种覆盖的测试逻辑:

示例代码(核心判定):
if (A && B) {  // 判定:整个表达式(A且B);条件:A、B两个原子条件执行逻辑1;  // 判定为真(T)的路径
} else {执行逻辑2;  // 判定为假(F)的路径
}
1. 判定覆盖的要求与测试用例
  • 判定覆盖目标:确保整个判定表达式(A && B)的「真、假两种结果都至少出现一次」,不关心内部单个条件的状态。
  • 满足要求的测试用例(仅需2个)
    • 用例1:A=T,B=T → 判定结果=T(执行逻辑1)
    • 用例2:A=F,B=任意 → 判定结果=F(执行逻辑2)
  • 覆盖情况
    • 判定的两种结果(T/F)都覆盖了;
    • 但条件 B 只用到了「T」(用例1),「F」的情况没测试到(用例2中 A=F 时,B 无论真假都不影响判定结果,属于“无效条件”)。
2. 条件覆盖的要求与测试用例
  • 条件覆盖目标:确保每个原子条件(AB)的「真、假两种状态都至少出现一次」,同时可能间接覆盖判定的结果。
  • 满足要求的测试用例(至少2个,需覆盖所有条件的T/F)
    • 用例1:A=T,B=F → 条件 A=TB=F(覆盖两个条件的一种状态),判定结果=F(执行逻辑2)
    • 用例2:A=F,B=T → 条件 A=FB=T(覆盖两个条件的另一种状态),判定结果=F(执行逻辑2)
    • (补充用例3:A=T,B=T → 判定结果=T,若需同时覆盖判定T/F,可增加此用例,但条件覆盖核心是“条件状态”)
  • 覆盖情况
    • 所有条件(AB)的「T/F」都覆盖了(A=T/FB=T/F 各出现一次);
    • 相比判定覆盖,额外测试了「A=T且B=F」「A=F且B=T」这两种判定覆盖没涉及的“条件组合”。

第三步:解读原句的核心逻辑

原句“条件覆盖要求每个条件在测试用例中至少为真一次,为假一次。与判定覆盖相比,条件覆盖增加了对判定条件的测试,确实增加了测试路径”,可拆解为两层核心:

1. 条件覆盖“增加了对判定条件的测试”——覆盖粒度更细
  • 判定覆盖只关心「整个判定的最终结果」(T/F),不深入内部条件的状态(比如示例中判定覆盖没测试 B=F 的情况);
  • 条件覆盖要求「每个条件的所有状态都要测」(A=T/FB=T/F 都必须出现),相当于把判定表达式“拆解开”,对每个原子条件单独验证,测试更细致,避免因单个条件异常导致的bug(比如 B=F 时是否有隐藏问题)。
2. 条件覆盖“确实增加了测试路径”——覆盖范围更广
  • 判定覆盖的测试路径仅围绕「判定的T/F」(示例中仅“执行逻辑1”“执行逻辑2”两条路径);

  • 条件覆盖为了满足“所有条件的T/F”,需要设计更多「条件组合」,这些组合可能对应不同的执行路径(或同一路径但内部条件状态不同的场景):

    • 示例中判定覆盖仅用到「A=T,B=T」「A=F,B=任意」两种组合;
    • 条件覆盖用到「A=T,B=F」「A=F,B=T」「A=T,B=T」三种组合,虽然部分组合最终执行同一路径(如前两种都执行逻辑2),但从“测试场景”来看,这些组合都是独立的路径(因为条件状态不同,可能触发不同的内部逻辑)。

    再举一个复杂例子(if (A || B && C)):

    • 判定覆盖只需2个用例(判定T/F);
    • 条件覆盖需要至少3个用例(覆盖 A=T/FB=T/FC=T/F),涉及的条件组合更多,对应的测试路径自然更丰富。

第四步:总结关键区别(表格更清晰)

维度判定覆盖条件覆盖
核心目标覆盖「判定表达式的T/F结果」覆盖「每个原子条件的T/F状态」
测试粒度粗(关注整体结果)细(关注内部条件)
测试用例数少(通常2个,等于判定结果数)多(至少等于条件数,需覆盖所有条件状态)
测试路径少(仅覆盖判定结果对应的路径)多(覆盖更多条件组合对应的场景)
缺陷发现能力弱(可能遗漏单个条件的异常)强(能发现条件本身的逻辑错误)

最终结论

原句的核心是:条件覆盖比判定覆盖的测试更深入、更全面——判定覆盖只“管结果”,条件覆盖既“管结果”又“管过程(条件状态)”,因此需要测试更多条件组合,自然拓展了测试路径,能发现判定覆盖遗漏的bug(比如单个条件的逻辑错误)。

条件覆盖一定包含判断覆盖吗?

不一定。条件覆盖和判断(判定)覆盖是两种不同的白盒测试覆盖准则,二者无绝对的“包含”关系,满足条件覆盖的测试用例,未必能满足判断覆盖。

核心原因:二者的覆盖目标不同

  • 判断覆盖:核心目标是覆盖每个判断表达式(如if (A && B))的真(T)和假(F)两种结果,确保所有分支都被执行。
  • 条件覆盖:核心目标是覆盖判断表达式中每个原子条件(如AB)的真(T)和假(F)两种状态,不直接要求覆盖判断的所有结果。

反例验证:满足条件覆盖但不满足判断覆盖

以简单的判断语句 if (A && B) 为例(AB 为原子条件):

  1. 条件覆盖的要求:需覆盖 A=TA=FB=TB=F 四种状态。
  2. 设计满足条件覆盖的测试用例
    • 用例1:A=T,B=F → 原子条件覆盖 A=TB=F,判断结果为 F
    • 用例2:A=F,B=T → 原子条件覆盖 A=FB=T,判断结果为 F
  3. 结果分析
    • 上述用例满足条件覆盖(所有原子条件的 T/F 状态均覆盖);
    • 但判断表达式的结果仅覆盖了 F,未覆盖 T,不满足判断覆盖的要求。

补充:特殊场景下的包含关系

只有当判断表达式的逻辑能确保“所有原子条件的 T/F 状态覆盖后,必然覆盖判断的 T/F 结果”时,条件覆盖才会包含判断覆盖。例如:

  • 单条件判断 if (A)
    • 条件覆盖需设计 A=TA=F,恰好覆盖判断的 TF 结果,此时条件覆盖等同于判断覆盖,自然包含。
  • 逻辑或判断 if (A || B)
    • 若设计用例 A=T,B=F(判断 T)和 A=F,B=T(判断 T),仍满足条件覆盖但不满足判断覆盖;
    • 若补充用例 A=F,B=F(判断 F),则同时满足两种覆盖。

总结

条件覆盖的核心是“原子条件的状态完整性”,判断覆盖的核心是“判断结果的分支完整性”,二者的覆盖目标不同,因此条件覆盖不一定包含判断覆盖。实际测试中,为避免逻辑遗漏,通常会选择“判断-条件覆盖”(同时满足两种覆盖的要求),兼顾分支与条件的完整性。

http://www.dtcms.com/a/582504.html

相关文章:

  • 网站建设类公司排名中国建筑人才网怎么样
  • Dify 迁移后常见问题解决方案与使用腾讯云cos上传文件 FILES_URL缺失
  • 郑州网站建设培训网站域名备案认证
  • 专业制作网站公司哪家好软件开发项目总结
  • 切换海外动态IP的方法
  • 设计业务网站外贸自建站类型
  • 网站建设在哪里发布网络优化工程师工资
  • Linux环境下的C语言编程(十七)
  • JAVA算法练习题day64
  • 小华HC32F460串口性能问题与处理思路
  • Java_Hashtable使用及扩容
  • Django序列化器
  • 跳表与B+树
  • 上海外贸网站优化自己做提卡网站
  • 学习日报 20251107|Nacos 注册同一服务多实例架构图
  • 营销型网站建设运营苏州园区
  • 广州站在哪个区酒店 网站构建
  • 网站开发的合同网络工程师中级职称报考条件
  • 相亲网站源码php模版wordpress听歌插件
  • 微网站 服务器在线设计logo图案免费
  • stm32 gpio 先写电平再初始化,是否可行?
  • 数字签名、 数字信封、数字证书
  • 马云的网站是谁建设的wordpress多广告位
  • Leetcode 47
  • 营销型网站分类自己服务器可以做网站
  • EtherCAT命令整理
  • Windows 常用命令行(CMD/PowerShell 通用,标注差异)
  • 小迪安全v2023学习笔记(一百四十五讲)—— Webshell篇魔改冰蝎打乱特征指纹新增加密协议过后门查杀过流量识别
  • 网站源码做exe执行程序域名被墙查询检测
  • HarmonyOS:ArkWeb在新窗口中打开页面