第2关:基本路径测试
任务描述
本关任务:填写缺失代码,完成白盒测试。
相关知识
为了完成本关任务,你需要掌握基本路径测试。
基本路径测试
除了逻辑覆盖,还有一种常用的白盒测试的测试方法:基本路径测试。基本路径测试是 Tom McCabe
提出的一种白盒测试技术。使用这种技术设计测试用例时,首先需要计算程序的环形复杂度,并用该复杂度为指南定义执行路径的基本集合,从该基本集合导出的测试用例可以保证程序中的每条语句至少执行一次,而且每个条件在执行时都将分别取真、假两种值。
基本路径测试的步骤为:
- 根据程序的执行过程画出流图
- 计算流图的环形复杂度
- 确定独立路径
- 设计测试用例
画流图
流图其实就是程序的流程图的简化版。其中只用圆圈来表示程序中的代码语句。下图是各种结构的示意图,流图中的箭头称为边或连接,代表控制流。任何过程设计都要被翻译成控制流图。其中,除了顺序结构,其他都为判定结构。
如果判断中的条件表达式是由一个或多个逻辑运算符 (OR
, AND
, NOR
)连接的复合条件表达式,则需要改为一系列只有单条件的嵌套的判断。
说了这么多,不如通过例子来画出程序的流图。假设程序是这样的:
1. void func(int recordnum, int type)
2. {
3. int x = 0;
4. int y = 0;
5. while(recordnum-->0)
6. {
7. if(type == 0)
8. {
9. x=y+2;
10. break;
11. }
12. else
13. {
14. if(type == 1)
15. {
16. x=y+10;
17. }
18. else
19. {
20. x=y+20;
21. }
22. }
23. }
24. }
代码中有一个while
循环结构,两个if
结构,在流图中能体现出这三个结构的话,流图就算画出来了。流图如下:
其中,红线表示while
循环结构,黄线表示第一个if
结构,蓝线表示第二个if
结构:
计算环形复杂度
环形复杂度是一种为程序逻辑复杂性提供定量测度的软件度量,将该度量用于计算程序的基本的独立路径数目,为确保所有语句至少执行一次测试数量的上界。独立路径必须包含一条在定义之前不曾用到的边。
有以下两种方法计算环形复杂度:
- 给定流图
G
的环形复杂度V(G)
,定义为V(G)=E-N+2
,E
是流图中边的数量,N
是流图中结点的数量; - 给定流图
G
的圈复杂度V(G)
,定义为V(G)=P+1
,P
是流图G
中判定结点的数量。
上面的流图的环形复杂度,可以分别使用这两种方法进行计算:
- 方法一:环形复杂度= 10 条边 - 8 个节点 + 2 ,即环形复杂度为 4;
- 方法二:环形复杂度= 3 个判定节点 + 1,即环形复杂度为 4。
确定独立路径
所谓独立路径就是从流图开始的地方到结束的地方的通路。独立路径的数量等于流图的环形复杂度。上面例子的环形复杂度为4
,所以独立路径总共有4
条。其独立路径已在下图中分别用橙色箭头表示。
设计测试用例
确定了独立路径后,就需要设计多组测试用例,覆盖所有的独立路径。因此测试用例可以是:
1. TestCase1: recordnum=0, 预期x=0
2. TestCase2: recordnum=1, type=0, 预期x=2
3. TestCase3: recordnum=1, type=1, 预期x=10
4. TestCase4: recordnum=1, type=2, 预期x=20
编程要求
设计满足基本路径测试的多个测试用例,用于对IsPrime
函数进行白盒测试。在右侧编辑器 Begin-End 区间补充代码,完成白盒测试。
IsPrime
函数是用来判断一个是否为素数,若是素数则会返回1
,否则返回0
。函数代码如下:
1. //判断一个数是否为素数,若是素数则返回1,否则返回0
2. int IsPrime(int number)
3. {
4. if(number <= 1)
5. {
6. return 0;
7. }
8. int i;
9. for(i=2; i < number; ++i)
10. {
11. if(number%i==0)
12. return 0;
13. }
14. return 1;
15. }
测试说明
平台会对你编写的代码进行测试。
测试输入: 预期输出: 总共4条路径,已覆盖4条路径
开始你的任务吧,祝你成功!
代码如下
#include"func.h"
#include<stdio.h>
//输入测试用例进行测试,其中number表示测试输入,result表示预期输出
//该函数内部会调用IsPrime函数,若实际输出与预期输出不一致,会给予提示
void RunTestCase(int number, int result);
void WhiteTest()
{
/*请按要求设计测试用例,并调用RunTestCase*/
/*********Begin********/
//素数(质数):大于1的自然数中,除了1和它本身以外不再有其他因数
RunTestCase(0, 0);//小于1,不是素数
RunTestCase(6, 0);//大于1,但是6=1*6,6=2*3,不是素数
RunTestCase(3, 1);//素数,i=2<3
RunTestCase(2, 1);//素数,i=number
/*********End*********/
}