可达性(Reach):语法可达 vs 语义可达
基础概念:什么是"可达"?
在控制流图(CFG)中,可达性描述的是:从某个节点出发,能不能"走到"另一个节点。
基本定义: 如果存在一条路径从 开始、到 结束,则称 可以到达 。
语法可达(Syntactic Reach)
图中存在这条路径 —— 只要边连着,就算可达。
这是一个纯图结构上的概念,不管程序逻辑、不管输入数据,只看图里有没有这条路。
举例:
1 → 2 → 5
↓
3 → 4 → 7
↓
6语法上可以到达 —— 因为图中存在 这条边/路径。
语义可达(Semantic Reach)
存在一个实际测试用例,能真正执行到这条路径 —— 光有边不够,得能跑起来。
这是程序执行层面的概念。有些路径在图上存在,但由于条件约束,任何输入都不可能让程序走这条路,那它就是语义不可达的。
两者的关键区别
| 判断依据 | 关注点 | |
|---|---|---|
| 语法可达 | 图的结构(有没有路径) | 图论 |
| 语义可达 | 实际测试用例能否执行到 | 程序逻辑 + 数据 |
语义可达一定语法可达,但语法可达不一定语义可达。
经典例子
func foo(x int) int {
if x > 0 {
if x < 0 { // 这个分支语法上存在,但永远不会执行
return -1
}
}
return 0
}在 CFG 中,x < 0 这个 true 分支语法可达(图中有这条路),但语义不可达(x > 0 且 x < 0 同时成立是不可能的)。
白盒测试
语句覆盖:使程序中的每条可执行语句至少执行一次
分支覆盖:使程序中的每个分支至少执行一次
条件覆盖:使程序中每一个条件的所有取值至少被执行一次
- 条件覆盖不一定是分支覆盖,分支覆盖不一定是条件覆盖
条件-分支覆盖:使程序中每个条件所有取值至少执行一次,并使每个判断本身可能判定结果也执行一次
条件组合覆盖:使程序中每个判定中条件各种组合都至少出现一次
