Skip to content

Commit df3a682

Browse files
committed
docs: improved 'White Box Testing'
1 parent ac483d0 commit df3a682

File tree

5 files changed

+123
-0
lines changed

5 files changed

+123
-0
lines changed

src/notes/Software-Testing-and-Maintenance/Chapter2-Software-Testing-Technology.md

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,126 @@ copyright: 转载请注明出处
188188
- 全部转换覆盖(All transitions coverage):每个转换至少被一次测试用例激活。
189189
- 全部路径覆盖(All path coverage):从入口到退出状态的所有可能路径都被测试用例覆盖。由于图中没有退出状态,因此需要识别从入口到每个状态的所有路径。
190190
- 全部循环覆盖(All circuits coverage):在图中,从同一个状态开始和结束的所有路径都被测试用例覆盖。
191+
192+
## 白盒测试
193+
194+
- 白盒测试,也称为`结构测试(structual testing)``逻辑驱动测试(logic driven testing)`,是一种从程序的`控制结构(control structure)`中导出测试用例的测试用例设计方法。
195+
- 白盒测试使用`被测单元(unit under test)`内部如何工作的信息,允许测试人员根据程序的`内部逻辑结构(internal logical structure)`和相关信息来设计和选择测试用例来测试程序。
196+
197+
### 覆盖率标准(Coverage Standard)
198+
199+
- 我们当然希望白盒测试覆盖尽可能多的分支,然而,由于循环的存在,遍历程序所有可能的路径是不现实的,例如一个`if-else`循环二十次,就有$2^20$种不同的可能性。因此我们有许多种不同的覆盖率标准,从低到高依次为:
200+
- 语句覆盖(Statement Coverage):意味着选择足够的测试用例,使得程序中的每条语句至少可以执行一次。
201+
- 判定覆盖/分支覆盖(Decision Coverage/Branch Coverage):执行足够的测试用例,使得程序中的每个分支至少通过一次
202+
- 条件覆盖(Condition Coverage):执行足够的测试用例,使得程序中判断的每个条件的每个可能值至少被执行一次;条件覆盖渗透到决策中的每个条件,但可能不满足决策覆盖的要求。
203+
- 判断/条件覆盖(Decision/Condiction Coverage):设计足够多的测试用例,运行所测程序,使程序中每个判断的每个条件的所有可能取值至少执行一次,并且每个可能的判断结果也至少执行一次,换句话说,即是要求各个判断的所有可能的条件取值组合至少执行一次;
204+
- 条件组合覆盖(Conditional combination coverage):执行足够的示例,以便每个决策中各种可能的条件组合至少出现一次。
205+
- 基本路径覆盖(basic logic test):设计足够多的测试用例,运行所测程序,要覆盖程序中所有可能的路径。这是最强的覆盖准则。但在路径数目很大时,真正做到完全覆盖是很困难的,必须把覆盖路径数目压缩到一定限度。
206+
- 前五种准则又被称为逻辑驱动测试(Logic-Driven Testing)方法
207+
208+
### 逻辑驱动测试(Logic-Driven Testing)
209+
210+
![例1](images/Chapter2-Software-Testing-technology/image-10.png)
211+
212+
- 这里,我们记$x\gt 3,\;z\lt 10,\; x==4, \;y\lt5$分别为$T_1,\;T_2,\;T_3,\;T_4$
213+
214+
#### 语句覆盖(Statement Coverage)
215+
216+
- 语句覆盖无法判断逻辑问题,因为它并不能对逻辑分支做检查,例如,将示例图中的第一个`&&`改为`||`,也并不能检查出来
217+
218+
#### 判定覆盖/分支覆盖(Decision Coverage/Branch Coverage)
219+
220+
- 它能够使每一个分支都获得每一种可能的结果,对于对于例1中,我只要设计两个例子,通过路径`ace``abd`或者通过路径`acd``abe`就可以达到判定覆盖,但是他也无法对判断条件进行检查,例如,我使用输入
221+
222+
```c
223+
x=4,y=5,z=5; //[a,b,d]
224+
x=2,y=5,z=5; //[a,c,e]
225+
```
226+
227+
当第二个条件错误地写成`y<5`时,也无法检测出来
228+
229+
#### 条件覆盖(Condition Coverage)
230+
231+
例1的程序有四个条件:
232+
233+
$$
234+
         A\gt1、B=0、A=2、X\gt1
235+
$$
236+
为了达到“条件覆盖”标准,需要执行足够的测试用例使得在a点有以下结果出现:
237+
$$
238+
A\gt1、A\le1、B=0、B\ne0
239+
$$
240+
以及在b点有以下结果出现:
241+
$$
242+
       A=2、A\ne2、X\gt1、X\le1
243+
$$
244+
现在只需设计以下两个测试用例就可满足这一标准:
245+
$$
246+
\begin{array}{c}
247+
A=2,B=0,X=4   \text{(沿路径ace执行)}\\
248+
A=1,B=1,X=1   \text{(沿路径abd执行)}
249+
\end{array}
250+
$$
251+
252+
- 但是它无法保证所有分支都被执行到,例如`IF A AND B THEN S`,我们设计用例为`(A,!B),(!A,B)`,那么`S`永远无法被执行到
253+
254+
#### 判断/条件覆盖(Decision/Condiction Coverage)
255+
256+
- 针对上述问题,引入了另一种覆盖标准“分支/条件覆盖”。其含义是执行足够多的测试用例,使得一个分支中的每个条件都可以获得各种可能的值,并且每个分支都可以获得各种可能的结果。
257+
- 对于例1,我们可以设计
258+
259+
|条件取值|通过路径|覆盖分支|
260+
|--|--|--|
261+
|$T_1,\;T_2,\;T_3,\;T_4$|abd|bd|
262+
|$-T_1,\;-T_2,\;-T_3,\;-T_4$|ace|ce|
263+
264+
- 然而,它无法判断条件的正确性,例如$x\gt 3 \&\& \lt 10$,对大多数编译器,当$x\gt 3$为真时,就不再会判断$z\lt 10$的情形了
265+
266+
#### 条件组合覆盖(Conditional combination coverage)
267+
268+
- 针对上述问题,提出了另一个标准“条件组合覆盖”。其含义是执行足够多的示例,使得每个决策中各种可能的条件组合至少出现一次。
269+
- 但是这种方法不能保证所有路径都被遍历到,因为它不要求分支的条件组合
270+
271+
#### 补充策略
272+
273+
- 任何方法都不可能提供一组"完整的"测试用例,因此总是需要补充,一种参考的黑盒法补充策略是:
274+
1. 使用边界值分析。
275+
2. 用等价分类法补充一些测试用例。
276+
3. 再用错误推测法附加测试用例。
277+
4. 检查上述例子的逻辑覆盖程度,如果未能满足某些覆盖标准,则再增加足够的测试用例。
278+
5. 如果功能说明中含有输入条件的组合情况,则一开始就可先用因果图(判定表)法。
279+
280+
### 基本路径测试(Basic Path Testing)
281+
282+
- 在例1中,我们可以很简单地遍历所有可能的路径,然而在实际程序中这是不可能的(指数爆炸!),但是我们可以通过一些手段进行剪枝,也就是压缩覆盖的路径数,比如通过只运行一次循环体
283+
- 下面介绍的方法就是在`程序控制图`的基础上,通过分析控制构造的`环行(圈,loop)复杂性`,导出基本可执行路径集合,从而设计测试用例的方法,设计出的测试用例要`保证在测试中程序的每一个可执行语句至少执行一次`
284+
- 通常包括四个步骤:
285+
1. 程序的控制流图:描述程序控制流的一种图示方法
286+
2. 程序圈复杂度:McCabe复杂性度量。从程序的环路复杂性可导出程序基本路径集合中的独立路径条数。
287+
3. 导出测试用例:根据圈复杂度和程序结构设计用例数据输入和预期结果。
288+
4. 准备测试用例:确保基本路径集中的每一条路径的执行
289+
- 一个方法:
290+
- 图形矩阵:是在基本路径测试中起辅助作用的软件工具,利用它可以实现自动地确定一个基本路径集。
291+
292+
#### 控制流图
293+
294+
![Control Flow Graph Symbols](images/Chapter2-Software-Testing-technology/image-11.png)
295+
296+
- 流图只有二种图形符号,图中的每一个圆称为流图的结点,代表一条或多条语句。流图中的箭头称为边或连接,代表控制流。
297+
- 任何过程设计都要被翻译成控制流图。
298+
- 在将程序流程图简化成控制流图时,应注意:
299+
- 在选择或多分支结构中,分支的汇聚处应有一个汇聚结点。
300+
- 边和结点圈定的区域叫做区域,当对区域计数时,图形外的区域也应记为一个区域。
301+
![Control Flow Gragh](images/Chapter2-Software-Testing-technology/image-12.png)
302+
- 如果判断中的条件表达式是由一个或多个逻辑运算符 (OR, AND, NAND, NOR) 连接的复合条件表达式,则需要改为一系列只有单条件的嵌套的判断。
303+
- 例如下列代码和对于图
304+
305+
```c
306+
if (a||b){
307+
x
308+
}else{
309+
y
310+
}
311+
```
312+
313+
![Nested Statement](images/Chapter2-Software-Testing-technology/image-13.png)
19.3 KB
Loading
22.3 KB
Loading
48.2 KB
Loading
16.6 KB
Loading

0 commit comments

Comments
 (0)