题目如下,回答问题1至3
int GetMaxDay (int year ,int month){
int maxday=0; //1
if (month>=1 && month <=12) { //2,3
if (month==2) { //4
if (year %4 ==0 ) { //5
if (year %100 ==0) { //6
if (year %400 ==0) {//7
maxday=29; //8
else //9
maxday=28;
}
else maxday=28; //10
}
else
maxday=28; //11
}
else { //12
if (month==4 || month ==6 || month==9 ||month ==11)//13,14,15,16
maxday=30; //17
else //18
maxday=31;
}
}
return maxday; //19
}
问题1、针对上述C程序给出满足100%DC(判定覆盖)所需的逻辑条件;
问题2、画出上述程序的控制流程图,并计算环路复杂度V(G);
问题3、给出问题2中的控制流图的线性无关路径;
问题1 解析:
①定义:
判定覆盖(Decision Coverage)又称为分支覆盖,其原则是设计足够的测试用例,使得程序中每个判定语句的取真和取假分支至少被执行一次。
除了双值的判定语句外,还有多值判定语句,如case语句,因此判定覆盖更一般的含义是:使得每一个判定获得每一种可能的结果至少一次。
问题2 解析:
(1)控制流图定义:
控制流图是描述陈谷控制流的一中图示方法,它由节点和定向边构成。控制流图的节点代表一个基本块,定向边代表控制流的方向。如果判断条件表达式是复合条件,即条件表达式是由一个或者多个逻辑运算符连接的表达式,则需要改变复合条件的判断为一系列单个条件的判断。本题中,if(month>=1 && month <=12)这条判断语句中的判定由两个条件组成,因此在画控制流图的时候要拆开成两个条件语句。同理if (month==4 || month==6 ||month ==9 ||month==11)这条判断语句中的判定条件由4个条件组成,因此在画控制流图的时候要拆成4个条件判断。如果复合条件之间是“&&”的关系,则拆开后反应在控制流图中是沿左子树往下,反之如果条件之间是“||”的关系,则在控制流图上是沿右子树往下。
图1 控制流图
(2)环路复杂度
McCabe 复杂性度量方式有如下三种:
1)通过控制流图的区域个数来计算
公式:V(G)=区域数
程序的环路复杂性为控制流图的区域数(即封闭的区域数+1)。
在下图中可以看到,有 1 和 2 两个封闭区域,因此,环路复杂度V(G)=2 + 1 = 3。
(2个封闭的区域+1个开放区域)
2)通过控制流图的边数和结点数来计算
公式:V(G) = e - n + 2
其中, e 即 edge ,表示图中边的数目; n 即 node ,表示结点个数。
下图中V(G)= e - n + 2 = 7条边 − 6个结点 + 2 = 3。
因此,环路复杂度V(G)=3。
3)通过控制流图中的判定结点个数来计算
公式:V(G) = P + 1
其中,P表示判定结点的数目。所谓判定节点数,即有多个分支的节点,比如下图中的节点 2 ,它可以走3或者5,这个时候它就需要做判断了。所以, 2 是一个判定节点。同样地,下面的 节点3 也像节点 2 一样分析。
因此,图中V(G)=2个判定结点+1 = 3,所以环路复杂度为3。
讲到这里,我们来给环路复杂性做个小结。事实上,程序的环路复杂性给出了程序基本路径集中的独立路径条数,这是确保可执行语句至少执行一次所必需的测试用例数目的上界。
问题3 解析:
从控制流图来看,一条线性无关路径是至少包含一条在其他线性无关路径中从未有过的边的路径。程序的环路复杂度等于线性无关路径的条数。所以本题有11条线性无关路径。
由上面的流程控制图可以看到,
(1)路径:1-2-19中,2-19是其他所有路径都没有经历的,所以是一条线性无关的路径;
(2)路径:1-2-3-19中,3-19是其他所有路径都没有经历的,所以是一条线性无关的路径;
同理:1-2-3-4-12-13-14-15-16-18-19,1-2-3-4-12-13-14-15-16-17-19,1-2-3-4-12-13-14-15-17-19,1-2-3-4-13-14-17-19,1-2-3-4-12-13-17-19,1-2-3-4-5-11-19,1-2-3-4-5-6-10-19,1-2-3-4-5-6-7-9-19,1-2-3-4-5-6-7-19是线性无关的路径。(红色路径都是其他路径没有包含的)