软测-第6个小时-白盒测试

32 小时通关|第 6 小时 白盒测试 总结

白盒测试:打开盒子,看程序内部代码结构、逻辑,又叫结构测试、逻辑驱动测试。和黑盒相反,黑盒不管代码,白盒研究代码。

一、白盒测试核心考点(必考)

白盒目标:覆盖代码逻辑,发现代码内部缺陷(语句错误、分支错误、路径错误) 主要测试方法:逻辑覆盖(重点!)、基本路径测试

二、逻辑覆盖(由弱→强排序,考试必背顺序)

从最低覆盖强度到最高:

  1. 语句覆盖:设计用例,保证每一行代码至少执行 1 次

最弱!只保证代码跑一遍,无法发现判断里面的错误 例子:if(a>1 && b>2),只要条件为真,整行执行,就算语句覆盖;判断里面写错了都发现不了。

  1. 判定覆盖(分支覆盖):每个判定(if)的取真、取假都要走一次

每个 if,既要满足条件成立,也要满足不成立。 注意:只关心整个 if 结果是真 / 假,不关心 if 里面每个子条件

  1. 条件覆盖:判定里面每一个子条件,取真、取假都至少一次

比如 if(a>1 && b>2) 子条件 1:a>1(真、假);子条件 2:b>2(真、假) ✅条件覆盖:a>1 取真、假;b>2 取真、假 ⚠坑:条件覆盖 ≠ 判定覆盖!有可能子条件真假都走到,但整个 if 判定永远全为 true 或者全 false(考试高频选择题坑)

  1. 判定 - 条件覆盖:同时满足【判定覆盖 + 条件覆盖】

所有判定真假都走;判定里所有子条件真假也都走。

  1. 条件组合覆盖(强度很高)

判定内所有子条件真假的全部组合,都覆盖一遍 if(a>1 && b>2) 一共 4 种组合 ①a>1 真,b>2 真 ②a>1 真,b>2 假 ③a>1 假,b>2 真 ④a>1 假,b>2 假

  1. 修正的条件判定覆盖 MCC(MC/DC,高频!)

含义:在判定里,每一个子条件独立影响整个判定结果。 航空、军工软件强制要求 MC/DC。 一句话:固定其他条件不变,只改变这一个子条件,能让整体 if 结果翻转。

✅覆盖强度排序(背诵!) 语句覆盖 < 判定覆盖 < 条件覆盖 < 判定条件覆盖 < 条件组合覆盖 MC/DC 介于判定条件覆盖 和条件组合覆盖之间

三、基本路径测试法(白盒另一大方法)

  1. 先画程序控制流图
  2. 计算环形复杂度(圈复杂度),圈复杂度 = 独立路径数量 环形复杂度 3 种计算公式(计算题必考) ① 边数 - 节点数 +2 ② 判定节点数量 +1 ③ 封闭区域数 +1

圈复杂度 = 需要设计的最少独立测试路径数量

  1. 根据独立路径,写测试用例

四、白盒适合 / 不适合

✅适合:单元测试(最常用!单元测试大多是白盒),检查代码逻辑、分支、路径 ❌不适合:大系统整体功能测试(系统测试一般黑盒)

五、黑盒 vs 白盒 一句话区分

  • 黑盒:不看代码,测功能、需求
  • 白盒:看代码内部结构,测逻辑、分支、语句路径

六、背诵短句

  1. 白盒测试又称结构测试,检查程序内部逻辑结构,多用于单元测试。
  2. 逻辑覆盖强度:语句 < 判定 < 条件 < 判定条件 < 条件组合;MC/DC 独立影响判定结果。
  3. 基本路径法:画控制流图,计算环形复杂度,得到独立路径,设计用例。
  4. 环形复杂度三种计算公式。

 

条件组合覆盖要列出全部 4 种子条件真假组合

if (A && B) { x = 1 }

代码:if(A && B) 两个子条件 A、B,每个都有真、假,2×2=4 组

  1. A 真,B 真 → if 整体为真,执行 x=1 ✅
  2. A 真,B 假 → if 整体为假,不执行 ✅
  3. A 假,B 真 → if 整体为假,不执行 ✅
  4. A 假,B 假 → if 整体为假,不执行 ✅

你刚才漏掉了第 4 组:A 假、B 假,这是考试容易丢分的地方。

逐个覆盖简单区分(这行代码为例)

  1. 语句覆盖:只需要第 1 组(A 真 B 真),代码执行一次 x=1 就达标。最弱。
  2. 判定覆盖(分支):需要【整体 if 为真】+【整体 if 为假】 选:A 真 B 真(真),A 假 B 假(假),2 组即可。
  3. 条件覆盖:A 取真、A 取假;B 取真、B 取假。 比如 A 真 B 假,A 假 B 真。 ⚠️大坑!这两组:A 有真有假,B 有真有假,满足条件覆盖,但是!整个 if 判定永远都是 false,没有走到 if 里面! → 条件覆盖不一定满足判定覆盖,选择题高频坑!
  4. 判定条件覆盖:同时满足判定覆盖 + 条件覆盖
  5. 条件组合覆盖:上面 4 组全部都要测(最强的逻辑覆盖)
  6. MC/DC(修正判定条件覆盖) 要求:单独改变一个条件,其他不动,能让整个判定结果反转
  • A&&B: ①A=T,B=T → T;改成 A=F,B=T →F (A 单独影响结果) ②A=T,B=T → T;改成 A=T,B=F →F (B 单独影响结果) MC/DC 只需要 2 组核心用例就够,不用 4 组。

一句话背强度顺序

语句覆盖 < 判定覆盖 < 条件覆盖 < 判定条件覆盖 < MC/DC < 条件组合覆盖

 

具体概念:

词法分析:拆单词(识别一个个最小符号,不关心句子结构)

语法分析:看句子结构(单词拼起来,符不符合语法规则)

类比中文句子:我吃苹果 词法分析:分出词语【我】【吃】【苹果】 语法分析:检查结构:主语 + 谓语 + 宾语,句子合法;如果是【吃 苹果 我】,词语都认识,但语序语法不对。

1、词法分析(Lexer 扫描)

任务:读原始字符串,去掉空格、换行,切分成记号 / Token(关键字、标识符、数字、运算符) 只识别单词,不管单词放一起合不合理。

✅例子:代码 int a = 10; 词法分析输出 Token 列表:

  1. int → 关键字
  2. a → 标识符(变量名)
  3. = → 赋值运算符
  4. 10 → 数字常量
  5. ; → 分号符号

哪怕写成 10 = a int; 词法分析照样能拆出:10 = a int ;,能识别所有单词,不会报错,它只管拆词。

2、语法分析(Parser 解析)

任务:拿上面的 Token 序列,按照语法规则,检查组合结构是否合法,生成语法树。

继续例子:

  • int a = 10; 语法分析:符合【类型 变量名 = 常量;】语法 → 合法 ✅
  • 10 = a int; 单词都没问题,但语法规则不允许数字写在等号左边,语序错误 → 语法报错 ❌

再举一个简单表达式例子 3 + 5 * 2

  1. 词法分析得到 Token:3 + 5 * 2
  2. 语法分析:识别表达式结构,知道*优先级高于+,构建语法树,判定表达式合法。

如果写 3 + * 5 词法:3 + * 5 (全部识别出记号) 语法:+ 后面不能直接跟 *,语法错误。

软考考点一句话背诵

  1. 词法分析:字符流 → Token 记号流;识别关键字、标识符、常数、运算符;最小单位是单词
  2. 语法分析:Token 流 → 语法树;检查语法结构、语序;最小单位是句子 / 表达式

 

态错误分析(软考考点,静态:不运行程序,直接读代码检查)

静态错误分析属于静态测试,不用执行代码,对源码做分析,找代码里的错误。 区分:动态测试要跑程序;静态全程不运行。

静态错误分析常见 4 类:

  1. 类型错误
  2. 引用未定义变量
  3. 语法错误(词法、语法错误)
  4. 接口 / 参数不匹配

举例 1:变量未定义(静态可查出)

int main(){
    b = 10;
    return 0;
}

变量b没有声明。不用运行代码,静态扫描就能发现:使用了未定义标识符。

举例 2:类型不匹配

int a = "hello";

把字符串赋值给整型变量。代码没跑,静态分析直接报类型错误。

举例 3:函数参数个数不匹配

int add(int x,int y){
    return x+y;
}
int main(){
    int res = add(10); //只传1个参数,函数要2个
}

不运行,静态检查发现:调用 add 参数数量不对。

举例 4:语法错误(少分号、括号不配对)

int a = 10
int b = 20;

第一行末尾缺少;。静态分析(编译器预处理阶段)直接捕获语法错误。

❗重要考点区分(选择题高频坑)

  • 静态错误:代码本身语法、定义、类型问题,程序根本跑不起来,编译阶段就能发现。
  • 动态错误:编译能通过,只有运行时才暴露。

背诵短句: 静态错误分析:不执行程序,检查源码,发现语法、变量、类型、参数的错误。 静态发现的错误,大多编译阶段就能拦截。

 

程序插桩(软考软件评测师考点)

一句话:程序插桩,就是在源代码里,手动 / 自动插入一小段额外代码(探针),用来收集程序运行信息,不改变原有业务逻辑。属于动态测试技术。

类比:给水管路上装流量计,水管(原程序)功能不变,流量计(插桩代码)统计流量。

例子

原有代码:统计两个数最大值

def max_num(x,y):
    if x>y:
        return x
    else:
        return y

插桩改造(加入探针代码)

def max_num(x,y):
    # ========== 插桩代码(探针)==========
    print(f"【插桩】进入函数,x={x},y={y}")
    # ====================================
    if x>y:
        # ========== 插桩代码 ==========
        print("【插桩】走if分支")
        # =============================
        return x
    else:
        # ========== 插桩代码 ==========
        print("【插桩】走else分支")
        # =============================
        return y

插桩代码作用:

  1. 看走了哪个分支(判定覆盖、分支覆盖统计)
  2. 记录输入值、执行次数
  3. 统计语句有没有被执行(覆盖率)

原代码逻辑完全没变,计算最大值结果不变,只是多打印日志用来观测运行路径。

软考常考插桩用途

用来做逻辑覆盖测试(语句、判定、条件覆盖),统计代码覆盖率。

考点区分

  • ✅程序插桩:动态,代码要运行;在源码加探针,采集执行信息
  • ✅静态错误分析:静态,不运行代码,扫描源码找错误

考试坑题举例

【单选】程序插桩技术属于() A 静态测试技术 B 动态测试技术 答案:B

补充另一个简单 C 语言小例子

原始:

if(a>10)
    s = s+1;

插桩后:

if(a>10)
{
    count++;  //插桩!记录这个分支被执行多少次
    s = s+1;
}

count++就是插入的探针,用来统计 if 分支执行次数。

 

一、静态测试方法(不运行程序)

1. 代码检查法

人工 / 工具阅读源码,走查、审查,找缺陷,不执行。 例子: 团队一起评审登录函数代码,看有没有变量未初始化、注释缺失、if 判断逻辑漏洞; 比如发现代码 if(user.pwd=123456) 这里用了赋值=而不是相等判断==,不用跑程序,看代码直接发现。

2. 静态结构分析法

分析程序内部结构:函数调用关系、控制流、模块接口、流程图,不运行。 例子: 工具扫描代码,画出函数调用图,发现 A 函数循环调用自己(递归无出口);或者查看模块之间参数传递类型是否匹配。只分析结构,不执行。

3. 静态质量度量法

静态计算软件质量指标,度量复杂度,不运行代码。 例子: 计算圈复杂度,算出 if、for、分支多少,判断代码好不好维护;统计代码行数、注释率、函数长度,评估代码可维护性。


二、动态测试白盒方法(必须运行程序,程序插桩常配合这两个)

1. 逻辑覆盖法(语句、判定、条件、判定条件、条件组合、路径覆盖)

设计测试用例,覆盖代码里的语句、分支、条件。 示例代码:

if a>10 and b<5:
    c = c + 1
  • 语句覆盖:设计用例,让这行c=c+1执行一次
  • 判定覆盖:覆盖【条件成立】和【条件不成立】两种分支

2. 基本路径测试法

基于控制流图 + 圈复杂度,导出独立基本路径,每条路径写测试用例,保证覆盖所有独立路径。 例子: 上面 if 代码,控制流图得到 2 条独立路径: 路径 1:判定为真 → 执行 c=c+1 路径 2:判定为假 → 不执行 c=c+1 给每条路径设计测试用例,覆盖全部基本路径。


✅ 考点速记(选择题)

  • 静态:代码检查(找 bug)、静态结构(看调用 / 控制流)、静态质量度量(算复杂度指标),不运行
  • 动态白盒:逻辑覆盖、基本路径测试,需要运行程序

坑点:圈复杂度计算本身属于静态质量度量;拿圈复杂度生成测试路径做测试,属于基本路径测试(动态)。

小选择题

下列属于静态质量度量的是? A 判定覆盖 B 计算圈复杂度 C 基本路径测试 D 程序插桩 答案:B

 

静态质量度量法(软考考点)

核心:不运行程序,从源码计算量化指标,评估代码质量,得到数字结果。 重点指标:圈复杂度、代码行数、注释率、函数长度、接口数量。

例子 1:圈复杂度(最常考)

源码片段:

int judge(int score)
{
    if(score >=90)
        return 1;
    else if(score >=60)
        return 2;
    else
        return 3;
}

静态工具直接扫描代码,算出圈复杂度:3。 含义:这个函数有 3 条独立路径;圈复杂度越高,代码越难测试、容易出错。

圈复杂度计算属于静态质量度量。 拿圈复杂度生成测试用例做基本路径测试,那一步是动态测试(区分坑点!)

例子 2:统计代码行数 & 注释率

对上面 judge 函数统计:

  • 有效代码行:6 行
  • 注释行:0 行
  • 注释率 = 注释行数 / 总代码行 注释率太低,度量结果提示:可读性差。

例子 3:度量函数长度

如果一个函数写了 200 行代码。静态度量直接给出数值,判定函数过长,可维护性差,建议拆分。

例子 4:度量模块接口数量

统计某个模块对外暴露的函数接口有 12 个。接口过多,度量结论:模块耦合度高。

高频考题区分

  • ✅静态质量度量:算出指标数字,评估质量好坏,不跑程序
  • ✅静态结构分析:看结构、调用关系、画控制流图,不一定计算质量指标
  • ✅代码检查法:人工 / 工具读代码,直接找 bug(比如少写 ==)

考题示例

【单选】下面属于静态质量度量的是() A. 检查函数之间调用关系 B. 计算代码圈复杂度 C. 人工审查源码发现 if 用赋值 = D. 插桩统计分支执行次数 答案:B

背诵短句:静态质量度量,是对源码做量化计算,得到指标,评估可维护性、复杂度。

静态三类汇总(背诵)

  1. 代码检查法:找缺陷(找 bug)
  2. 静态结构分析法:分析结构(调用、控制流、接口)
  3. 静态质量度量法:计算指标(圈复杂度、注释率、代码行数)

 

 

统一用同一段伪代码,所有覆盖都拿它举例,不容易乱:

if(A && B)
{
    语句S;
}

判定:A && B 里面包含 2 个独立条件:条件 A,条件 B 语句 S:if 里面那行代码


1. 语句覆盖 SC

✅教材定义:所有语句至少执行 1 次。 只需要让 A&&B = 真,进入 if,跑一遍 S 就行。 测试用例:A=T,B=T

  • 结果:S 被执行,满足语句覆盖 ⚠️缺点:完全不测试分支为假的情况。如果&&写成||,这个用例发现不了。

2. 判定覆盖 DC(分支覆盖)

✅教材定义:每个判定,取到至少一次真、一次假。 判定A&&B要有【真】、【假】两种结果。 2 组用例:

  1. A=T,B=T →判定 = 真(走 if 内 S)
  2. A=F,B=T →判定 = 假(不走 S)

只要判定真假都走到,就满足判定覆盖。 书上原话:比语句覆盖强。 ⚠️坑:条件本身的真假不一定全部覆盖,上面例子里条件 B 永远是 T。

3. 条件覆盖 CC

✅教材定义:判定里每一个独立条件的可能取值至少出现一次。 这里两个条件 A、B。 A 要有 T、F;B 要有 T、F。 用例:

  1. A=T,B=F
  2. A=F,B=T ✅A 取 T/F;B 取 T/F,满足条件覆盖 ⚠️大坑(考试高频): 这两个用例,判定结果都是false! 👉条件覆盖 ≠ 判定覆盖,有可能判定永远没有 true 分支。

4. 条件判定组合覆盖 CDC(判定条件覆盖)

目标:同时满足【判定覆盖】+【条件覆盖】 既要:判定取 T、F;又要每个条件 A、B 都取 T、F 用例:

  1. A=T,B=T →判定 = T
  2. A=F,B=F →判定 = F ✅A:T/F;B:T/F;判定 T/F 都有。 ⚠️缺陷:不会把条件所有排列组合全部覆盖。

5. 多条件覆盖 MCC

目标:判定内所有条件的全部组合都测一遍。 A、B 一共 4 种组合:

  1. A=T,B=T
  2. A=T,B=F
  3. A=F,B=T
  4. A=F,B=F ✅全部组合都覆盖。 缺点:条件一多,用例爆炸。3 个条件就要 8 组,4 个条件 16 组。

6. 修正判定条件覆盖 MC/DC(重点!软考高频)

要求:

  1. 满足判定覆盖;
  2. 每个条件取 T/F;
  3. 单独改变这一个条件,其他条件不变,就能让判定结果反转。 对于 A && B 用例:
  4. T T →真
  5. T F →假 (固定 A=T,B 一变,判定翻转)
  6. F T →假 (固定 B=T,A 一变,判定翻转)

不需要 4 组全部组合,比 MCC 用例少很多,航空、军工软件强制要求 MC/DC。


一句话强弱排序(书上顺序)

语句覆盖 < 判定覆盖 < 条件覆盖 < 判定条件覆盖 < MC/DC < 多条件覆盖

考试选择题常考坑

  1. 条件覆盖,不一定满足判定覆盖(刚才例子可以验证)
  2. MC/DC 不需要全部条件组合,MCC 才是全部组合
  3. 语句覆盖最弱,只保证代码行跑一遍,分支可能漏测

 

 

基本路径测试法(白盒,书上 4 个步骤 + 同一个例子)

一句话概括:基本路径测试,算出程序最少需要多少条独立路径,设计用例覆盖这一组基础路径,属于白盒测试。 适用:模块详细设计、源代码。

书上的 4 步(原文)

  1. 根据源码,画出控制流图
  2. 计算控制流图的环路复杂性 V (g)
  3. 找出线性无关的基本路径集合
  4. 写测试用例,每条基本路径都跑一遍

环路复杂性 V (g) 的含义:等于基本路径的数量,就是你最少要准备几个用例。

举简单例子

伪代码:

if(A && B)
{
    S1;
}
S2;

第 1 步:画控制流图

节点: 1 开始 →2(判定 A&&B) 判定 2: ✅真 →3(执行 S1)→4(执行 S2)→结束 ❌假 →4(执行 S2)→结束

第 2 步:计算环路复杂性 V (g)(3 种计算公式,考试必考)

公式任选其一,结果一样:

  1. V(g)=边数 − 节点数 +2
  2. V(g)=判定节点数量 +1(判定就是 if 这种分支点,最省事!)
  3. 数封闭区域数量

这里判定节点只有 1 个(if) V(g)=1+1 =2 👉环路复杂性 = 2,最少 2 条基本路径

第 3 步:找出线性无关基本路径集合

路径 1:开始 →判定 2【真】→S1 →S2 →结束 路径 2:开始 →判定 2【假】→S2 →结束

“线性无关”:两条路线,至少有一段代码走的不一样。 不用把所有可能路径全部测完,只要这一组基础路径就行。

第 4 步:写测试用例

路径 1:A=T,B=T,走 if 里面 S1 路径 2:A=F,任意 B,不走 S1

考试重点

  1. 环路复杂性 = 基本路径的条数
  2. 公式:判定节点数量 + 1,做题最快
  3. 基本路径 ≠ 全部所有路径,是最小的一组独立路径

和判定覆盖对比:判定覆盖只保证判定取真假;基本路径法直接算出独立通路,生成路径用例。

再举个带两个 if 的例子巩固

if(A)
    S1;
if(B)
    S2;

判定节点:2 个(A、B) V (g)=2+1=3,需要 3 条基本路径。

 

===================================================================

白盒分为【静态白盒测试】+【动态白盒测试】(完整汇总,补上静态部分,适配 32 小时通关)

白盒测试总体分为两大类:静态白盒(不运行代码)、动态白盒(运行代码,前面咱们学的逻辑覆盖、基本路径都属于这块)

一、静态白盒测试(不执行程序,看代码 / 文档,选择题高频)

核心:不跑代码,人工或者工具分析源码

  1. 代码审查(同行评审):小组人工开会读代码,找缺陷。
  2. 静态结构分析:画控制流图、调用关系图,分析模块之间调用。
  3. 静态质量度量:计算环路复杂度、代码行数、注释率等指标。
  4. 静态错误分析
    • 类型 / 语法检查(变量未定义、类型不匹配)
    • 边界检查、变量引用检查(使用未初始化变量)
    • 接口检查:函数入参、返回值匹配

一句话:静态白盒,只看,不运行。

二、动态白盒测试(运行代码,就是刚才那一大块)

核心:运行程序,根据代码内部控制结构设计用例

1. 白盒动态测试 4 条设计原则

  1. 保证模块所有独立路径至少使用一次
  2. 所有逻辑值,True、False 都要测试
  3. 在上下边界、可操作范围运行所有循环
  4. 检查内部数据结构,保证有效

2. 逻辑覆盖 6 种(强度由弱到强)

语句覆盖<判定覆盖<条件覆盖<判定条件覆盖<MC/DC 修正判定条件覆盖<条件组合覆盖

  1. 语句覆盖:所有语句至少执行一次(最弱)
  2. 判定覆盖:每个判定取 T、F
  3. 条件覆盖:判定内每个条件取 T、F(⚠️不一定满足判定覆盖)
  4. 判定 - 条件覆盖:判定 + 条件都覆盖
  5. MC/DC:每个条件能够独立改变判定结果(安全类软件常用)
  6. 条件组合覆盖:判定内部所有条件真假全部组合(逻辑覆盖里最强)

3. 基本路径测试法(大题考点)

4 步骤:

  1. 根据源码导出控制流图
  2. 计算环路复杂性 V (g) 公式:V (g)= 判定节点 + 1;V (g)= 边 - 节点 + 2;数封闭区域
  3. 找出线性无关基本路径集
  4. 设计测试用例,覆盖每条基本路径

V (g) 的值 = 基本路径的数量;基本路径≠全部路径

4. 其他白盒方法(单选)

  1. 域测试:变量定义域、边界检查
  2. 符号测试:符号变量代替数值做推导
  3. Z 路径覆盖:简化循环,循环只测 0 次、1 次
  4. 程序变异测试(错误驱动)
    • 弱变异:执行到修改语句即可
    • 强变异:执行代码,输出结果不同才算杀死变异

✅易混大坑(必背)

  1. 静态白盒:不运行代码,代码审查、静态分析
  2. 动态白盒:必须运行代码,逻辑覆盖、基本路径、Z 路径、变异测试
  3. 白盒≠全部是动态!静态白盒也是白盒测试!选择题最爱挖坑。

完整一句话速记

白盒分动静两类:静态只读不运行,审查代码查问题;动态跑起源代码,逻辑覆盖路径测。

posted on 2026-10-15 17:08  轻微强迫症  阅读(14)  评论(0)    收藏  举报