10.15软件测试作业--计算星期
软件分析与测试
基于代码的测试实验报告——计算星期
一、实验目的
(1)巩固基于代码的测试技术,能熟练应用控制流覆盖方法、逻辑覆盖方法等设计测试用例;
(2)学习测试用例的书写。
二、实验内容
计算日期是星期几
已知公元1年1月1日是星期一。请编写一个程序,只要输入年月日,就能自动回答当天是星期几。
要求:
为测试该程序的方便,请将计算星期的算法尽量放入一个函数中,输入和输出检查可用其它函数来处理。为简单起见,不考虑公元前的日期。
提示:
(a) 解答思路:计算输入日期与公元1年1月1日所相差的天数,具体如下:
总天数=公元1年到输入日期上一年年底天数+输入年份的1月到上月月底天数+输入日期的天数
(b) 闰年满足条件:(year%4==0)&&(year%100!=0)||(year%400==0)
(1)画出程序的流图;
(2)分别以判定覆盖、条件覆盖、MC/DC覆盖标准设计测试用例,并写出每个测试用例的执行路径;
(3)请采用基本路径覆盖(兼顾循环)、数据流覆盖标准对程序进行测试,并给出具体测试用例信息。
(4)请采用变异测试的方法对你的原程序进行适当变异,获得3~4个变异体,执行上述(2)~(3)中的测试用例集,分析变异体的存活率,评估测试用例集的故障敏感度。
(5)通过你的测试,请总结你所使用测试方法发现的Bug。
要求:设计测试用例时,每种覆盖方法的覆盖率尽可能达到100%
三、实验要求
- (1)根据题目要求编写测试用例
- (2)撰写实验报告
- (3)有关的实现程序请附到实验报告中
- (4)实验报告命名规则:学号后两位+姓名_基于代码的测试(计算星期)¬
四、实验报告
(1)程序代码
#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)程序控制流图
重要节点对应代码
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;
(3)判定覆盖
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)条件覆盖
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覆盖
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)基本路径覆盖
圈复杂度:18(条边)-14(个节点)+ 2 = 6
基本路径集
若测试年份大于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 |
2000 8 8 |
2 |
(7)数据流覆盖
程序的控制流图
计算相关定义、引用集合、DU(定义/引用)路径
结点的定义、引用变量
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} |
边的引用变量
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} |
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] |
基于代码的覆盖——数据流覆盖
共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)变异测试
变异体一:
与源代码相比改变闰年判定条件中的常数值
bool leapYear_1(int year)
{
return year%40==0 || year%100!=0 && year%4==0;
}
变异体二:
与源代码相比改变闰年判定条件中的或条件
bool leapYear_2(int year)
{
return year%400==0 && year%100!=0 && year%4==0;
}
变异体三:
与源代码相比,改变闰年判定条件中的等式判定条件
bool leapYear_3(int year)
{
return year%400==0 && year%100==0 && year%4==0;
}
变异体四:
与源代码相比,省略闰年判定中的某个条件
bool leapYear_4(int year)
{
return year%400==0 || year%100!=0;
}
变异体改变汇总
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% |