10.15软件测试作业--计算星期


#基于代码的测试实验报告——计算星期


##一、实验目的

1
2
(1)巩固基于代码的测试技术,能熟练应用控制流覆盖方法、逻辑覆盖方法等设计测试用例;
(2)学习测试用例的书写。


##二、实验内容

###计算日期是星期几

1
已知公元1年1月1日是星期一。请编写一个程序,只要输入年月日,就能自动回答当天是星期几。


1
2
3
4
5
6
7
要求:
为测试该程序的方便,请将计算星期的算法尽量放入一个函数中,输入和输出检查可用其它函数来处理。为简单起见,不考虑公元前的日期。

提示:
(a) 解答思路:计算输入日期与公元1年1月1日所相差的天数,具体如下:
总天数=公元1年到输入日期上一年年底天数+输入年份的1月到上月月底天数+输入日期的天数
(b) 闰年满足条件:(year%4==0)&&(year%100!=0)||(year%400==0)

1
2
3
4
5
6
(1)画出程序的流图;
(2)分别以判定覆盖、条件覆盖、MC/DC覆盖标准设计测试用例,并写出每个测试用例的执行路径;
(3)请采用基本路径覆盖(兼顾循环)、数据流覆盖标准对程序进行测试,并给出具体测试用例信息。
(4)请采用变异测试的方法对你的原程序进行适当变异,获得3~4个变异体,执行上述(2)~(3)中的测试用例集,分析变异体的存活率,评估测试用例集的故障敏感度。
(5)通过你的测试,请总结你所使用测试方法发现的Bug。
要求:设计测试用例时,每种覆盖方法的覆盖率尽可能达到100%

##三、实验要求

  • (1)根据题目要求编写测试用例
  • (2)撰写实验报告
  • (3)有关的实现程序请附到实验报告中
  • (4)实验报告命名规则:学号后两位+姓名_基于代码的测试(计算星期)¬

##四、实验报告

###(1)程序代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include<string>
using namespace std;

bool leapYear(int year);
int main()
{
cout << "请输入年月日:" << endl;
int a, b, c;
string day;
cin >> a >> b >> c;
int i, result = 0;
for(i=1;i<=a-1;i++)
{
result+=(leapYear(i)+365)%7;
}
for(i=1;i<=b-1;i++)
{
if(i==1||i==3||i==5||i==7||i==8||i==10||i==12)
result+=31;
else if(i==4||i==6||i==9||i==11)
result+=30;
else if(i==2)
result+=(28+leapYear(a));
}
result+=c;
result%=7;

cout <<a<<"年"<<b<<"月"<<c<<"日是星期" << result << endl;
return 0;
}

bool leapYear(int year)
{
return year%400==0 || year%100!=0 && year%4==0;
}


###(2)程序控制流图

1
2
3
4
5
6
7
重要节点对应代码
Node2 for(i=1;i<=a-1;i++)
Node4 for(i=1;i<=b-1;i++)
Node5 if(i==1||i==3||i==5||i==7||i==8||i==10||i==12)
Node7 if(i==4||i==6||i==9||i==11)
Node9 if(i==2)
Node11 year%400==0 || year%100!=0 && year%4==0;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
st=>start:  start
op_00=>operation: 1
cond_for_0=>condition: 2
op_for_0=>operation: 3

cond_for_1=>condition: 4

cond_if_1=>condition: 5
cond_if_2=>condition: 7
cond_if_3=>condition: 9

op_0=>operation: 6
op_1=>operation: 8
op_2=>operation: 10
op_3=>operation: For

op_4=>operation: 12
op_5=>operation: 11 leap


st->op_00->cond_for_0
cond_for_0(yes)->op_for_0->cond_for_0
cond_for_0(no)->cond_for_1
cond_for_1(yes)->cond_if_1
cond_for_1(no)->op_4
cond_if_1(yes)->op_0->op_3
cond_if_1(no)->cond_if_2
cond_if_2(yes)->op_1->op_3
cond_if_2(no)->cond_if_3
cond_if_3(yes)->op_2->op_5->op_3
cond_if_3(no)->op_3->cond_for_1

###(3)判定覆盖

1
2
P1  year%400==0 || year%100!=0 && year%4==0;    闰年判定
注释:由于for循环的不确定性,在此,执行路径省略


编号 测试用例 覆盖判定 输出结果
1 2008 8 8 P1 5
2 2007 7 8 -P1 7

编号 测试用例 闰年判定 输出结果
1 2008 8 8 True 5
2 2007 7 8 False 7

###(4)条件覆盖

1
2
3
4
T3 year%400==0 
T2 year%100!=0
T3 year%4==0; 闰年判定
注释:由于for循环的不确定性,在此,执行路径省略


编号 测试用例 条件覆盖 输出结果
1 2000 8 8 T1 -T2 T3 2
2 2008 8 8 -T1 T2 T3 5
3 2001 8 8 -T1 T2 -T3 3

编号 测试用例 year%400==0 year%100!=0 year%4==0 输出结果
1 2000 8 8 True False True 2
2 2008 8 8 False True True 5
3 2001 8 8 False True False 3

###(5)MC/DC覆盖

1
2
3
4
5
6
7
P1 year%400==0 || year%100!=0 && year%4==0;    闰年判定
T1 year%400==0
T2 year%100!=0
T3 year%4==0

注释:由于for循环的不确定性,在此,执行路径省略
根据MC/DC特性,编写下述用例

编号 测试用例 T1 T2 T3 闰年判定 输出结果
1 1900 8 8 F F T F 3
2 2001 8 8 F T F F 3
3 2008 8 8 F T T T 5
1 2000 8 8 T F T T 2

###(6)基本路径覆盖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
st=>start:  start
op_00=>operation: 1
cond_for_0=>condition: 2
op_for_0=>operation: 3

cond_for_1=>condition: 4

cond_if_1=>condition: 5
cond_if_2=>condition: 7
cond_if_3=>condition: 9

op_0=>operation: 6
op_1=>operation: 8
op_2=>operation: 10
op_3=>operation: For

op_4=>operation: 12
op_5=>operation: 11 leap


st->op_00->cond_for_0
cond_for_0(yes)->op_for_0->cond_for_0
cond_for_0(no)->cond_for_1
cond_for_1(yes)->cond_if_1
cond_for_1(no)->op_4
cond_if_1(yes)->op_0->op_3
cond_if_1(no)->cond_if_2
cond_if_2(yes)->op_1->op_3
cond_if_2(no)->cond_if_3
cond_if_3(yes)->op_2->op_5->op_3
cond_if_3(no)->op_3->cond_for_1

1
圈复杂度:18(条边)-14(个节点)+ 2 = 6

1
2
3
基本路径集
若测试年份大于1,那么所有路径都会被走过一遍,所以基本路径的长度与输入年份成正比,下罗列一种路径:
S-1-2-3-2-4-5-6-4-5-7-8-4-5-7-9-10-11-4-5-7-9-4-12-E

1
设计测试用例
编号 测试用例 输出结果
1 2000 8 8 2

###(7)数据流覆盖

程序的控制流图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
st=>start:  start
op_00=>operation: 1
cond_for_0=>condition: 2
op_for_0=>operation: 3

cond_for_1=>condition: 4

cond_if_1=>condition: 5
cond_if_2=>condition: 7
cond_if_3=>condition: 9

op_0=>operation: 6
op_1=>operation: 8
op_2=>operation: 10
op_3=>operation: For

op_4=>operation: 12
op_5=>operation: 11 leap


st->op_00->cond_for_0
cond_for_0(yes)->op_for_0->cond_for_0
cond_for_0(no)->cond_for_1
cond_for_1(yes)->cond_if_1
cond_for_1(no)->op_4
cond_if_1(yes)->op_0->op_3
cond_if_1(no)->cond_if_2
cond_if_2(yes)->op_1->op_3
cond_if_2(no)->cond_if_3
cond_if_3(yes)->op_2->op_5->op_3
cond_if_3(no)->op_3->cond_for_1

计算相关定义、引用集合、DU(定义/引用)路径

1
结点的定义、引用变量
Node Def Use
1 {a,b,c,i,result}
2 {i} {a}
3 {result} {i}
4 {i} {b}
5 {i}
6 {result}
7 {i}
8 {result}
9 {i}
10 {result,a}
11 {year} {year}
12 {result} {a,b,c,result}

1
边的引用变量
Edge Use
(1,2) {a,i}
(2,3) {i}
(3,2)
(2,4)
(4,5) {i,b}
(5,7) {i}
(7,9) {i}
(5,6) {result}
(7,8) {result}
(9,10) {result}
(10,11) {a}
(4,12) {a,b,c,result}

1
DU(定义/引用)路径









DU(定义/引用)路径
Variable DU Pairs DU Paths


a
(1,2)
[1,2]


(1,10)

[1,2,4,5,7,9,10]


(1,12)
[1,2,4,5,7,9,10,11,12]

b
(1,4)
[1,2]


(1,12)

[1,2,4,5,7,9,10,11,12]

c
(1,12)
[1,2,4,5,7,9,10,11,12]


result

(3,6)
[3,2,4,5,6]


(3,8)

[3,2,4,5,7,8]


(3,10)
[3,2,4,5,7,9,10]


(3,12)
[3,2,4,5,7,9,10,11,4,12]


(12,12)
[12]

基于代码的覆盖——数据流覆盖

1
2
3
4
5
6
7
8
9
共11条DU路径,8条唯一
[1,2]
[1,2,4,5,7,9,10]
[1,2,4,5,7,9,10,11,12]
[3,2,4,5,6]
[3,2,4,5,7,8]
[3,2,4,5,7,9,10]
[3,2,4,5,7,9,10,11,4,12]
[12]

###(8)变异测试

####变异体一
与源代码相比改变闰年判定条件中的常数值

1
2
3
4
bool leapYear_1(int year)
{
return year%40==0 || year%100!=0 && year%4==0;
}


####变异体二
与源代码相比改变闰年判定条件中的或条件

1
2
3
4
bool leapYear_2(int year)
{
return year%400==0 && year%100!=0 && year%4==0;
}


####变异体三
与源代码相比,改变闰年判定条件中的等式判定条件

1
2
3
4
bool leapYear_3(int year)
{
return year%400==0 && year%100==0 && year%4==0;
}


####变异体四

与源代码相比,省略闰年判定中的某个条件

1
2
3
4
bool leapYear_4(int year)
{
return year%400==0 || year%100!=0;
}


####变异体改变汇总

1
2
3
4
5
P:return year%400==0 || year%100!=0 && year%4==0;
M1:return year%40==0 || year%100!=0 && year%4==0;
M2:return year%400==0 && year%100!=0 && year%4==0;
M3:return year%400==0 && year%100==0 && year%4==0;
M4:return year%400==0 || year%100!=0;


#####测试用例集
| 编号 | a |b |c
|—| —– | —- | —- |
|t1|2008|8|8
|t2|2007|7|8
|t3|2000 |8| 8
|t4|2001| 8| 8
|t5|1900| 8| 8


#####测试执行结果
| 测试编号 | P |M1|M2|M3|M4|杀死的变异体
|— | —– | —- | —- | —- | —- |—-|
|t1|5|5|4|4|5|M2 M3
|t2|7|7|7|7|1|M4
|t3|2|2|1|2|2|M2
|t4|3|3|3|3|4|M4
|t5|3|3|3|3|3|无


#####测试用例集的充分性
| 测试用例| 测试用例集的充分性|
|——-| —- |— | —– |
|t1|50%|
|t2|25%|
|t3|25%|
|t4|25%|
|t5|0%|