- NextDate函数讲解
- 格式:ppt
- 大小:2.11 MB
- 文档页数:6
一、实验目的:掌握黑盒测试中的决策表测试法,并对被测程序设计测试用例。
二、实验环境操作系统:Windows XP + SP2 /win7三、实验内容1、编写一个NextDate函数。
2、掌握黑盒测试中的决策表测试法的基本步骤。
3、使用决策表法设计测试用例,对编写的函数实施测试,总结分析测试结果。
四、实验步骤1、编写一个NextDate函数。
(C语言、C++)2、根据黑盒测试的决策表测试法设计测试用例。
3、根据测试用例实施测试,并记录测试结果。
五、实验代码#include <iostream>using namespace std;int a,b,c,y,m,d;<<"/n";return 1;}elsereturn a;}<<b<<"."<<c<<"\n"<<"\n";return 0;}}<<"\n";cout << "年份范围是1960-2060"<<"\n";cout<<"年"<<"\n";cin >>y;cout<<"月"<<"\n";cin>>m;cout<<"日"<<"\n";cin>>d;a=y;b=m;c=d;NextDate ( y, m, d);}return 0;}六、测试用例表NxetDate函数求解给定某个日期的下一个日期的动作桩如下:变量day加1操作;变量day复位操作;变量month加1操作;变量month复位操作;变量year加1操作NxetDate函数的求解关键是日和月的问题,所以可以在下面的条件桩的基础上建立决策表M1={month:month有30天};M2={month:month有31天,12月除外};M3={month:month是12月};M4={month:month是2月};D1={day:1=<day<=27};D2={day:day=28};D3={day:day=29};D4={day:day=30};D5={day:day=31};Y1={year:year是闰年};Y2={year:year不是闰年}NxetDate函数决策表NxetDate函数的测试用例组七、测试用例执行结果1、Test Case 1~32、Test Case 43、Test Case 54、Test Case 6~95、Test Case 106、Test Case 11~147、Test Case 158、Test Case 169、Test Case 1710、Test Case 1811、Test Case 1912、Test Case 2013、Test Case 21~22八、实验总结1、通过本次实验,学会编写一个NextDate函数。
Next_day()函数的⽤法⼀、定义NEXT_DAY(date,char)date参数为⽇期型,char:为1~7或Monday/Mon~Sunday/指定时间的下⼀个星期⼏(由char指定)所在的⽇期,char也可⽤1~7替代,1表⽰星期⽇,2代表星期⼀。
还可以是星期⼀、星期⼆。
星期⽇,即 monday,thusday.....(看是什么字符集的)格式:NEXT_DAY(DATE,WEEKDAY) 即 NEXT_DAY(⽇期,星期⼏)NEXT_DAT函数返回输⼊⽇期开始,紧随其后的指定星期对应的⽇期,weekday可以⽤全称,也可以⽤缩写(如'monday','tuesday','wed')例:next_day(to_date('1999.11.24','yyyy.mm.dd'),'friday') 返回 1999年11⽉26⽇例:next_day(to_date('1999.11.24','yyyy.mm.dd'),'wed') 返回 1999年11⽉01⽇注:1999年11⽉24⽇是星期三,第⼆个参数是星期五,是两天后。
第⼆个例⼦由于⽇期正好是星期三,只能⽤下⼀个星期三⽇期。
⼆、⽤法1、select next_day(sysdate,1) from dual;或者select NEXT_DAY (sysdate, 'MONDAY ') FROM DUAL;求当前系统时间的下⼀星期⼀的时间,若报错现实“周中的⽇⽆效”,是因为字符集的问题,说明你的oracle的字符集是简体中⽂的,即:simplified chinese的可以设置字符集alter session set NLS_DATE_LANGUAGE = American; 将当前对话改为英⽂。
NextDate函数部分代码public class NextDate {/**年*/private int year;/**月*/private int month;/**日*/private int day;/**构造方法*@param year、month、day:年、月、日;*/public NextDate(int year, int month, int day){ this.year = year;this.month = month;this.day = day;}/**构造方法*/public NextDate(){year = 1;month = 1;day = 1;}/**获得年*@return获得年*/public int getyear(){return this.year;}/**获得月份*@return获得月份*/public int getmonth(){return this.month;}/**获得日期*@return获得日期*/public int getday(){return this.day;}/**判断闰年*@return是否闰年*/public boolean isleap(){if(( this.year%4==0 && this.year%100!=0 )||(this.year%400==0)){ return true;}else {return false;}}/**计算当前日期的下一天*/public void nextday( ){switch(this.month){case 1:case 3:case 5:case 7:case 8:case 10:if(this.day == 31){this.month = this.month + 1;this.day = 1;}else{this.day = this.day + 1;}break;case 4:case 6:case 9:case 11:if(this.day == 30){this.month = this.month + 1;this.day = 1;}else{this.day = this.day + 1;}break;case 12:if(this.day == 31){this.month = 1;this.day = 1;this.year = this.year + 1;}else{this.day = this.day + 1;}break;case 2:if(this.isleap()){if(this.day == 29){this.day = 1;this.month = 3;}else{this.day = this.day + 1;}}else{if(this.day == 28){this.day = 1;this.month = 3;}else{this.day = this.day + 1;}}break;}}/***计算下一天*@param date日期*@return下一天的日期*/public NextDate nextday( NextDate date ){ switch(date.month){case 1:case 3:case 5:case 7:case 8:case 10:if(date.day == 31){date.month = date.month + 1;date.day = 1;}else{date.day = date.day + 1;}break;case 4:case 6:case 9:case 11:if(date.day == 30){date.month = date.month + 1;date.day = 1;}else{date.day = date.day + 1;}break;case 12:if(date.day == 31){date.month = 1;date.day = 1;date.year = date.year + 1;}else{date.day = date.day + 1;}break;case 2:if(date.isleap()){if(date.day == 29){date.day = 1;date.month = 3;}else{date.day = date.day + 1;}}else{if(date.day == 28){date.day = 1;date.month = 3;}else{date.day = date.day + 1;}}break;}return date;}/***判断日期是否有效*@param date日期*@return是否有效*/public boolean isDate(NextDate date){boolean flag = true;if((date.year<0)||(date.year>2050)){flag = false;}if((date.month<1)||(date.month>12)){flag = false;}else{switch(date.month){case 1:case 3:case 5:case 7:case 8:case 10:case 12:if((date.day > 31)||(date.day<1))flag = false;break;case 4:case 6:case 9:case 11:if((date.day > 30)||(date.day<1)){flag = false;}break;case 2:if(date.isleap()){if((date.day > 29)||(date.day < 1))flag = false;}else{if((date.day > 28)||(date.day < 1))flag = false;}break;}}return flag;}}。
软件测试NextDate函数决策表测试法实验报告一、实验目的:掌握黑盒测试中的决策表测试法,并对被测程序设计测试用例。
二、实验环境操作系统:Windows XP + SP2 /win7三、实验内容1、编写一个NextDate函数。
2、掌握黑盒测试中的决策表测试法的基本步骤。
3、使用决策表法设计测试用例,对编写的函数实施测试,总结分析测试结果。
四、实验步骤1、编写一个NextDate函数。
(C语言、C++)2、根据黑盒测试的决策表测试法设计测试用例。
3、根据测试用例实施测试,并记录测试结果。
五、实验代码#include using namespace std; int a,b,c,y,m,d; //判断是否为闰年bool Feb(int y){ if((2060-y)%4==0) return 1; elsereturn 0;} //年份的累加int NextYear(int y){ a=y+1;if(a>2060){cout<return a;} //月份的累加int NextMonth(int m){ b=m+1; if(b==13){ b=1;NextYear(y);} return b;} //天数的累加int NextDay(int d){ c=d+1;//大月满32天月份加1 if(c==32){if(m==1|m==3|m==5|m==7|m==8|m==10|m==12) {c=1;NextMonth(m);}}//小月满31天月份加1 if(c==31){if(m==4|m==6|m==9|m==11) {c=1;NextMonth(m);}}//若为闰年,2月满30天,月份加1 if(c==30){if(Feb(y)&&m==2){ c=1; b=3;}}//若不是闰年,2月满29天,月份加1 if(c==29){if(!Feb(y)&&m==2){ c=1; b=3;}} return c;} //NextDate函数int NextDate ( int y, int m, int d){ if(y<1900|y>2060|m<1|m>12|d<1|d>31){cout<if(m==4|m==6|m==9|m==11&&d==31) {cout<if(Feb(y)&&m==2&&d>29) {cout<if(!Feb(y)&&m==2&&d>28){cout<NextDay(d);cout<//main函数 int main() {while(1){cout << \请输入正确格式的日期.\cout << \年份范围是1960-2060\cout<>y; cout<>m;cout<>d; a=y; b=m; c=d;NextDate ( y, m, d);} return 0;}六、测试用例表NxetDate函数求解给定某个日期的下一个日期的动作桩如下:变量day加1操作;变量day复位操作;变量month加1操作;变量month复位操作;变量year加1操作NxetDate函数的求解关键是日和月的问题,所以可以在下面的条件桩的基础上建立决策表M1={month:month有30天};M2={month:month有31天,12月除外}; M3={month:month是12月};M4={month:month是2月};感谢您的阅读,祝您生活愉快。
nextdate函数的代码#include#includevoid main(){int year,month,day;void nextdate(int ,int ,int );printf("请输入年份(范围在1912-2050之间):");scanf("%d",&year);printf("请输入月份(范围在1-12之间):");scanf("%d",&month);printf("请输入日期(范围在1-31之间):");scanf("%d",&day);printf("%d年%d月%d日的下一天是:",year,month,day);nextdate(year,month,day);}void nextdate(int year,int month,int day){int leap( int );switch(month){case 1:case 3:case 5:case 7:case 8:case 10:if(day>=1&&day<31)day=day+1;else if(day==31){day=1;month=month+1;}elseprintf("输入数据错误!\n"); break;case 12:if(day>=1&&day<31) day=day+1;else if(day==31){day=1;month=1;year=year+1;}else{printf("输入数据错误!\n"); exit(0);}break;case 4:case 6:case 9:case 11:if(day>=1&&day<30) day=day+1;else if(day==30){day=1;month=month+1;}else{printf("输入数据错误!\n");exit(0);}break;case 2:if(day>=1&&day<28)day=day+1;else if(!leap(year)&&day==28){day=1;month=month+1;}else if(leap(year)&&day==28)day=day+1;else if(leap(year)&&day==29){day=1;month=month+1;}else{printf("输入数据错误!\n");exit(0);}}printf("%d年%d月%d日\n",year,month,day); } int leap(int yy){return (yy%400==0||(yy%4==0&&yy%100!=0)); }。
NextData函数一、问题描述程序有三个输入变量month、day、year(month、day和year均为整数值,并且满足:1≤month≤12、1≤day≤31、1900≤year ≤2050。
),分别作为输入日期的月份、日、年份,通过程序可以输出该输入日期在日历上下一天的日期。
例如,输入为2005年11月29日,则该程序的输出为2005年11月30日。
请用黑盒测试方法设计测试用例。
二、程序界面计算下一天的程序代码见附录。
三、设计测试用例1. 用边界值测试方法设计测试用例用健壮性测试法设计测试用例,按照下列步骤进行:(1)分析各变量的取值健壮性测试时,各变量分别取:略小于最小值、最小值、略高于最小值、正常值、略低于最大值、最大值和略大于最大值。
month:-1,1,2,6,11,12,13;day:-1,1,2,15,30,31,32year:1899,1900,1901,1975,2049,2050,2051;(2)测试用例数有n个变量的程序,其边界值分析会产生6n+1个测试用例。
这里有3个变量,因此会产生19个测试用例。
(3)设计测试用例,见表1-1。
NextDate函数的复杂性来源于两个方面:一是输入域的复杂性(即输入变量之间逻辑关系的复杂性),二是确定闰年的规则。
但是在进行健壮性测试时,没有考虑输入变量之间的逻辑关系,也没有考虑和闰年相关的问题,因此在设计测试用例时存在遗漏问题,比如和判断闰年相关的日期:2008.2.29、1999.2.28等。
表1-1NextDate函数测试用例2. 用基于判定表的方法设计测试用例(1)分析各种输入情况,列出为输入变量month、day、year划分的有效等价类。
month变量的有效等价类:M1 = { month = 4,6,9,11 }M2 = { month = 1,3,5,7,8,10 }M3 = { month = 12 }M4 = { month = 2 }day变量的有效等价类:D1={日期:1≤日期≤27}D2={日期:日期=28}D3={日期:日期=29}D4={日期:日期=30}D5={日期:日期=31}year变量的有效等价类:Y1 = { year是闰年}Y2 = { year不是闰年}(2)分析程序规格说明,结合以上等价类划分的情况给出问题规定的可能采取的操作(即列出所有的动作桩)。
NextDate函数测试用例选择NextDate函数,是因为它可以说明输入定义域中的依赖性问题,这使得这个例子成为基于决策表测试的一个完美例子,因为决策表可以突出这种依赖关系。
从前面对等价类测试的分析我们知道,等价类分析假设所有的变量都是独立的。
如果变量确实是独立的,则使用类的笛卡尔积是有意义的。
如果变量之间在输入定义域中存在逻辑依赖关系,则这些依赖关系在笛卡尔积中就会丢失(说抑制可能更确切)。
决策表格式通过使用“不可能动作”概念表示条件的不可能组合,使我们能够强调这种依赖关系。
下面将对NextDate函数的决策表描述做三次尝试。
第一次尝试标识合适的条件和动作,假设首先从分析等价类集合开始。
M1= {月份:每月有30天};M2 = {月份:每月有31天};M3二{月份:此月是2月}D1 = {日期:1<0期W 28}; D2 = {日期:日期=29}; D3 = {日期=30}; D4 = {日期=31}Y1 = {年:年是闰年}; Y2 = {年:年不是闰年}如果我们希望突出不可能的组合,则可以建立具有以下条件和动作的有限项决策表。
(请注意,年变量对应的等价类收缩为下表的一个条件。
)有2处条规则的第一袂尝试这个决策表会有256条规则,其中很多是不可能的。
如果要显示为什么这些规则是不可能的,可将动作修改为:al:月份中的天数太多;a2:不能出现在非闰年中;a3:计算NextDate.第二次尝试如果我们将注意力集中到NextDate函数的闰年问题上,则可以修改已有的等价类集合。
为了说明另一种决策表表示方法,这一次采用扩展项决策表开发,并更仔细地研究动作桩。
在构建扩展项决策表时,必须保证等价类构成输入定义域的真划分。
如果规则项之间存在“重叠”,则会存在冗余情况,使得多个规则都能够满足。
这里,Y2是一组1812〜2012之间的年份,并除以4, 2000除外。
M1= {月份:每月有30天}; M2 = {月份:每月有31天}; M3二{月份:此月是2月}D1 = {日期:1<0期W 28}; D2 = {日期:日期=29}; D3 = {日期=30}; D4 = {日期=31}Y1 = {年:年=2000}; Y2 = {年:年是闰年}; Y3 = {年:年是平年}从某种意义上说,我们采用的是“灰盒”技术,因为更仔细地研究了NextDate 函数。
1、使用等价类划分法为NextDate函数设计测试用例:NextDate函数包含三个输入变量month、day和year(要求month、day和year 均为整数值,并且满足:1≤month≤12; 1≤day≤31;1912≤year≤2050),函数的输出为输入日期后一天的日期。
(1)列出输入域等价类表(包括有效和无效等价类)。
(2)根据(1)中的等价类,设计能覆盖所有等价类的测试用例,要求包括输入数据和预期输出,并指出各个测试用例所覆盖的等价类编号。
2、某城市电话号码由三部分组成,分别是:地区码——空白或者三位数字;前缀——非‘0’或‘1’开头的三位数字;后缀——4位数字。
假定被测程序能接受一切符合上述规定的电话号码,拒绝所有不符合规定的电话号码。
(1)列出输入域等价类表(包括有效和无效等价类)。
(2)根据(1)中的等价类表,设计能覆盖所有等价类的测试用例,要求包括输入数据和预期输出,并指出各个测试用例覆盖的等价类编号。
3、使用基本路径测试方法测试以下程序段:V oid sort(int irecordnum,int itype)1{2Int x = 0;3Int y = 0;4While( irecordnum -- >0 )5{6If( itype == 0)7Break;8Else9If(itype == 1)10x = x+10;11Else12y = y+20;13}14}说明:写在程序段某些行开头数字(1~14)是对每条语句的编号。
(1)画出程序的控制流程图(用题中给出的语句编号表示)。
(2)计算上述程序段的环形复杂度。
(3)导出基本路径集,列出程序的独立路径(用题中给出的语句编号表示)。
请根据(3)中的独立路径,设计测试用例的输入数据和预期输出。
4、使用基本路径测试方法测试以下程序段:Int IsGood( int grade ){① If (grade <= 100){② If( grade >= 80 ){③ If(year >= 90 )④ Result = 2; //优秀Else⑤ Result = 1; //良好}Else if(grade >= 0)⑥ Result = 0; //合格Else⑦ Result = -1; //分数为负数}Else⑦ Result = -1; //分数大于100⑧ Return Result;}说明:写在程序段某些行开头数字(①~⑧)是对应语句的编号。
#include<>void main(){int year,month,day;void nextdate(int ,int ,int );printf("请输入年份(范围在1912-2050之间):");scanf("%d",&year);printf("请输入月份(范围在1-12之间):");scanf("%d",&month);printf("请输入日期(范围在1-31之间):");scanf("%d",&day);printf("%d年%d月%d日的下一天是:",year,month,day);nextdate(year,month,day);}void nextdate(int year,int month,int day){int leap( int );switch(month){case 1:case 3:case 5:case 7:case 8:case 10:if(day>=1&&day<31)day=day+1;else if(day==31){day=1;month=month+1;}elseprintf("输入数据错误!\n");break;case 12:if(day>=1&&day<31)day=day+1;else if(day==31){day=1;month=1;year=year+1;}{printf("输入数据错误!\n");exit(0);}break;case 4:case 6:case 9:case 11:if(day>=1&&day<30)day=day+1;else if(day==30){day=1;month=month+1;}else{printf("输入数据错误!\n");exit(0);}break;case 2:if(day>=1&&day<28)day=day+1;else if(!leap(year)&&day==28){day=1;month=month+1;}else if(leap(year)&&day==28)day=day+1;else if(leap(year)&&day==29){day=1;month=month+1;}else{printf("输入数据错误!\n");exit(0);}}printf("%d年%d月%d日\n",year,month,day); }int leap(int yy){return (yy%400==0||(yy%4==0&&yy%100!=0)); }。
NextData函数一、问题描述程序有三个输入变量month、day、year(month、day和year均为整数值,并且满足:1≤month≤12、1≤day≤31、1900≤year ≤2050。
),分别作为输入日期的月份、日、年份,通过程序可以输出该输入日期在日历上下一天的日期。
例如,输入为2005年11月29日,则该程序的输出为2005年11月30日。
请用黑盒测试方法设计测试用例。
二、程序界面计算下一天的程序代码见附录。
三、设计测试用例1. 用边界值测试方法设计测试用例用健壮性测试法设计测试用例,按照下列步骤进行:(1)分析各变量的取值健壮性测试时,各变量分别取:略小于最小值、最小值、略高于最小值、正常值、略低于最大值、最大值和略大于最大值。
month:-1,1,2,6,11,12,13;day:-1,1,2,15,30,31,32year:1899,1900,1901,1975,2049,2050,2051;(2)测试用例数有n个变量的程序,其边界值分析会产生6n+1个测试用例。
这里有3个变量,因此会产生19个测试用例。
(3)设计测试用例,见表1-1。
NextDate函数的复杂性来源于两个方面:一是输入域的复杂性(即输入变量之间逻辑关系的复杂性),二是确定闰年的规则。
但是在进行健壮性测试时,没有考虑输入变量之间的逻辑关系,也没有考虑和闰年相关的问题,因此在设计测试用例时存在遗漏问题,比如和判断闰年相关的日期:2008.2.29、1999.2.28等。
表1-1NextDate函数测试用例2. 用基于判定表的方法设计测试用例(1)分析各种输入情况,列出为输入变量month、day、year划分的有效等价类。
month变量的有效等价类:M1 = { month = 4,6,9,11 }M2 = { month = 1,3,5,7,8,10 }M3 = { month = 12 }M4 = { month = 2 }day变量的有效等价类:D1={日期:1≤日期≤27}D2={日期:日期=28}D3={日期:日期=29}D4={日期:日期=30}D5={日期:日期=31}year变量的有效等价类:Y1 = { year是闰年}Y2 = { year不是闰年}(2)分析程序规格说明,结合以上等价类划分的情况给出问题规定的可能采取的操作(即列出所有的动作桩)。
附录A:NextDate函数源代码void NextDate(int year,int month,int day);void main(){int year=0,month=0,day=0;NextDate(year,month,day);}void NextDate(int year,int month,int day){printf("请输入年份:\n");scanf(“%d”,&year);while(!(year>=1811 && year<=2013)){printf("年份超过界限,请重新输入\n");scanf(“%d”,&year);}printf("请输入月份:\n");scanf(“%d”,&month);while (month>12||month<1){printf("月份超过界限,请重新输入\n");scanf(“%d”,&month);}printf("请输入日期:\n");scanf(“%d”,&day);while (day>31||day<1){printf("日期输入有误,请重新输入\n");scanf(“%d”,&day);}if((year%4==0 && year%100!=0) || (year%400==0)) /*检查闰年*/ {int i=0;i=day-29;while(month==2&&i>0){printf("本月是闰月,请在1-29之间从新输入日期\n");scanf(“%d”,&day);}if(month==2&&day==29){month=3;day=1;}else day++;}else day++;/*月底计算*/;switch(month){case 1:case 3:case 5:case 7:case 8:case 10:if (day==32){month++;day=1;printf("明天是:%d/%d/%d\n",year,month,day);}break;case 2:if(day==29){month=3;day=1;printf("明天是:%d/%d/%d\n",year,month,day);}break;case 4:case 6:case 9:case 11:if(day==31){month++;day=1;printf("明天是:%d/%d/%d\n",year,month,day);}break;case 12:if(day==32){year++;month=1;day=1;printf("明天是:%d/%d/%d\n",year,month,day);}break;}printf("明天是:%d/%d/%d\n",year,month,day);}。
NextDate函数测试用例选择NextDate函数,是因为它可以说明输入定义域中的依赖性问题,这使得这个例子成为基于决策表测试的一个完美例子,因为决策表可以突出这种依赖关系。
从前面对等价类测试的分析我们知道,等价类分析假设所有的变量都是独立的。
如果变量确实是独立的,则使用类的笛卡尔积是有意义的。
如果变量之间在输入定义域中存在逻辑依赖关系,则这些依赖关系在笛卡尔积中就会丢失(说抑制可能更确切)。
决策表格式通过使用“不可能动作”概念表示条件的不可能组合,使我们能够强调这种依赖关系。
下面将对NextDate函数的决策表描述做三次尝试。
第一次尝试标识合适的条件和动作,假设首先从分析等价类集合开始。
M1 = {月份:每月有30天}; M2 = {月份:每月有31天};M3 = {月份:此月是2月}D1 = {日期:1≤日期≤28};D2 = {日期:日期=29};D3 = {日期=30};D4 = {日期=31}Y1 = {年:年是闰年};Y2 = {年:年不是闰年}如果我们希望突出不可能的组合,则可以建立具有以下条件和动作的有限项决策表。
(请注意,年变量对应的等价类收缩为下表的一个条件。
)这个决策表会有256条规则,其中很多是不可能的。
如果要显示为什么这些规则是不可能的,可将动作修改为:a1:月份中的天数太多;a2:不能出现在非闰年中;a3:计算NextDate。
第二次尝试如果我们将注意力集中到NextDate函数的闰年问题上,则可以修改已有的等价类集合。
为了说明另一种决策表表示方法,这一次采用扩展项决策表开发,并更仔细地研究动作桩。
在构建扩展项决策表时,必须保证等价类构成输入定义域的真划分。
如果规则项之间存在“重叠”,则会存在冗余情况,使得多个规则都能够满足。
这里,Y2是一组1812~2012之间的年份,并除以4,2000除外。
M1 = {月份:每月有30天}; M2 = {月份:每月有31天};M3 = {月份:此月是2月}D1 = {日期:1≤日期≤28};D2 = {日期:日期=29};D3 = {日期=30};D4 = {日期=31}Y1 = {年:年=2000};Y2 = {年:年是闰年};Y3 = {年:年是平年}从某种意义上说,我们采用的是“灰盒”技术,因为更仔细地研究了NextDate函数。
Java⿊盒测试之nextDate函数测试⽬录⼀、实验⽬的⼆、实验内容三、实验要求四、实验过程五、缺陷分析⼀、实验⽬的(1)掌握应⽤⿊盒测试技术进⾏测试⽤例设计。
(2)掌握对测试⽤例进⾏优化设计⽅法。
⼆、实验内容⽇期问题测试以下程序:该程序有三个输⼊变量month、day、year(month、day和year均为整数值,并且满⾜:1≤month≤12、1≤day≤31和1900≤year≤2050),分别作为输⼊⽇期的⽉份、⽇、年份,通过程序可以输出该输⼊⽇期在⽇历上隔⼀天的⽇期。
例如,输⼊为2004 年11⽉30⽇,则该程序的输出为2004年12⽉1⽇。
(1)划分等价类,按照等价类划分法设计测试⽤例;(2)编写nextDate函数;(3)掌握Junit4的⽤法,使⽤Junit4测试nextDate函数。
JUnit4是JUnit框架有史以来的最⼤改进,其主要⽬标便是利⽤Java5的Annotation特性简化测试⽤例的编写。
掌握Junit4定义的⼀些常见Annotations:org.junit.Testorg.junit.Beforeorg.junit.Afterorg.junit.BeforeClassorg.junit.AfterClassorg.junit.Ignoreorg.junit.runner.RunWithorg.junit.runners.Suite.SuiteClassesorg.junit.runners.Parameterized.Parameters三、实验要求(1)根据题⽬要求编写测试⽤例;(2)准备nextDate函数,使⽤Junit4测试执⾏测试;(3)撰写实验报告。
四、实验过程(1)根据题⽬要求编写测试⽤例1)划分等价类并编号输⼊数据有效等价类⽆效等价类年(1) 1900到2050内的闰年整数(10) year<1900(2) 1900到2050内的平年整数(11) year>2050(12) 其他输⼊⽉(3) 1,3,5,7,8,10,12内的整数(13) month<1(4) 4,6,9,11内的整数(14) 12<month(5) 2(15) 其他输⼊⽇(6) 1~28(16) day<1(7) 29(17) year为闰年 month=2时,29<day(8) 30(18) year为⾮闰年 month=2时,28<day(9) 31(19) month=1,3,5,7,8,10,12时,31<day(20) month=4,6,9,11时,30<day(21) day>31(22) 其他输⼊2)为有效等价类设计测试⽤例序号测试数据期望结果覆盖范围12016 2 29下⼀天是2016年3⽉1⽇!(1)(5)(7)22017 1 28下⼀天是2017年1⽉29⽇!(2)(3)(6)32017 1 31下⼀天是2017年2⽉1⽇!(2)(3)(9)42017 4 30下⼀天是2017年5⽉1⽇!(2)(4)(8)52017 12 31下⼀天是2018年1⽉1⽇!(2)(3)(9)3)为每⼀个⽆效等价类⾄少设计⼀个测试⽤例序号输⼊数据期望结果覆盖范围61899 3 1年的值不在指定范围之内(10)72051 3 1年的值不在指定范围之内(11)8205% 3 1⽆效的输⼊⽇期!(12)91901 -1 1⽉的值不在指定范围之内(13)101901 13 1⽉的值不在指定范围之内(14)111901 1% 1⽆效的输⼊⽇期!(15)121901 1 -1⽇的值不在指定范围之内(16)132016 2 30⽇的值不在指定范围之内(17)142017 2 29⽇的值不在指定范围之内(18)152017 3 32⽇的值不在指定范围之内(19)162017 4 31⽇的值不在指定范围之内(20)172017 4 32⽇的值不在指定范围之内(21)182017 4 3%⽆效的输⼊⽇期!(22)(2)编写nextDate函数,使⽤Junit4测试执⾏测试被测代码package io.shentuzhigang.demo.blackbox;import java.util.regex.Pattern;/*** @author ShenTuZhiGang* @version 1.0.0* @date 2021-05-06 15:43*/public class Date {private static final Pattern pattern = pile("^[-\\+]?[\\d]*$");public static String nextDate(String s_year, String s_month, String s_day) { //检测是否存在⽆效字符if (!(isInteger(s_year) && isInteger(s_month) && isInteger(s_day))) {return "⽆效的输⼊⽇期!";}//将字符串转为intint year = Integer.parseInt(s_year);int month = Integer.parseInt(s_month);int day = Integer.parseInt((s_day));boolean flag = false;if (year < 1900 || year > 2050) {return ("年的值不在指定范围之内");} else if (month > 12 || month < 1) {return ("⽉的值不在指定范围之内");} else if (day > 31 || day < 1) {return ("⽇的值不在指定范围之内");}switch (month) {case 1:case 3:case 5:case 7:case 8:case 10:if (day == 31) {day = 1;month = month + 1;} else {day = day + 1;}break;case 4:case 6:case 9:case 11:if (day == 30) {day = 1;month = month + 1;} else if (day == 31) {flag = true;} else {day = day + 1;}break;case 12:if (day == 31) {day = 1;month = 1;year = year + 1;} else {day = day + 1;}break;case 2: {if (((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)) { // 闰年if (day == 29) {day = 1;month = 3;} else if (day < 29) {day = day + 1;} else {flag = true;// day超过29}} else {//⾮闰年if (day == 28) {day = 1;month = 3;} else if (day < 28) {day = day + 1;} else {flag = true;}}}break;default:}if (year > 2050) {return ("年的值不在指定范围之内");} else if (flag) {return ("⽇的值不在指定范围之内");} else {return ("下⼀天是" + year + "年" + month + "⽉" + day + "⽇!"); }}/*** 判断输⼊字符串是否是整数型** @param str* @return*/public static boolean isInteger(String str) {return pattern.matcher(str).matches();}}测试代码package io.shentuzhigang.demo.blackbox;import org.junit.Assert;import org.junit.Test;import org.junit.runner.RunWith;import org.junit.runners.Parameterized;import org.junit.runners.Parameterized.Parameters;import java.util.Arrays;import java.util.Collection;/*** @author ShenTuZhiGang* @version 1.0.0* @date 2021-05-06 15:43*/@RunWith(Parameterized.class)public class DateTests {private String input1;private String input2;private String input3;private String expected;@Parameterspublic static Collection<?> prepareData(){String [][] object = {// 有效等价类{"2016","2","29","下⼀天是2016年3⽉1⽇!"},{"2017","1","28","下⼀天是2017年1⽉29⽇!"},{"2017","1","31","下⼀天是2017年2⽉1⽇!"},{"2017","4","30","下⼀天是2017年5⽉1⽇!"},// ⽆效等价类{"1899","3","1","年的值不在指定范围之内"},{"2051","3","1","年的值不在指定范围之内"},{"205%","3","1","⽆效的输⼊⽇期!"},{"1901","-1","1","⽉的值不在指定范围之内"},{"1901","13","1","⽉的值不在指定范围之内"},{"1901","1%","1","⽆效的输⼊⽇期!"},{"1901","1","-1","⽇的值不在指定范围之内"},{"2016","2","30","⽇的值不在指定范围之内"},{"2017","2","29","⽇的值不在指定范围之内"},{"2017","3","32","⽇的值不在指定范围之内"},{"2017","4","31","⽇的值不在指定范围之内"},{"2017","4","32","⽇的值不在指定范围之内"},{"2017","4","3%","⽆效的输⼊⽇期!"}};return Arrays.asList(object);}public DateTests(String input1,String input2,String input3,String expected){this.input1 = input1;this.input2 = input2;this.input3 = input3;this.expected = expected;}@Testpublic void testDate(){String result = Date.nextDate(input1,input2,input3);Assert.assertEquals(expected,result);}}测试结果五、缺陷分析1.⽤例?发⽣故障的原因是程序先判断day为29就变为3⽉1⽇,⽽不先判断是否为闰年,于是⽤例?的输出结果为2007-3-1⽽不是⽆效输⼊⽇期。
NextDate面向对象实现nextdate包是一个实现“输入3个参数:年(year)、月(month)、日(day),返回输入日期后面的那个日期”的面向对象程序。
该包由1个抽象类(CalendarUnit)、4个具体类(Date、Month、Year、Day)组成。
其UML图如下:下面是详细描述。
①CalendarUnit类职责:提供一个操作在子类中设置属性值;提供一个布尔操作,说明在子类中的属性是否可以增1。
package nextdate;public abstract class CalendarUnit {protected int currentPos;protected void setCurrentPos(int pCurrentPos){currentPos = pCurrentPos;}protected int getCurrentPos(){return currentPos;}protected abstract boolean increment();}②Date类职责:Date对象由Day、Month和Year 3个对象组成。
Date对象通过这三个对象的布尔增量方法增1。
如果Day和Month对象不能加1,则Date根据需要重新设置Day和Month;如果是一年的最后一天,则Year也要加1。
printDate操作通过Day、Month和Year对象中的get()成员函数,以mm/dd/yyyy格式输出日期。
package nextdate;public class Date {private Day d;private Month m;private Year y;public Date(int pMonth, int pDay, int pYear) {y = new Year(pYear);m = new Month(pMonth,y);d = new Day(pDay,m);}public void increment(){if(! d.increment()){if(! m.increment()){y.increment();m.setMonth(1,y);}d.setDay(1,m);}}public void printDate(){System.out.println(m.getMonth()+"/"+d.getDay()+"/"+y.getYear()); }}③Day类职责:Day对象有一个私有Month属性,用以决定Day取值是要加1还是复位。
NextDate函数的等价类测试用例NextDate是一个三变量函数,即月份、日期和年,这些变量的有效值区间定义如下:M1={月份:1≤月份≤12}D1={日期:1≤日期≤31}Y1={年:1812≤年≤2012}无效等价类:M2={月份:月份<1}M3={月份:月份>12}D2={日期:日期<1}D3={日期:日期>31}Y2={年:年<1812}Y3={年:年>2012}由于有效类的数量等于独立变量的个数,因此只有弱一般等价类测试用例出现,并且与强一般等价类测试用例相同:用例ID 月份日期年预期输出WN1,SN1 6 15 1912 1912年6月16日用例ID 月份日期年预期输出WR1 6 15 1912 1912年6月16日WR2 -1 15 1912 月份不在有效值域1..12中WR3 13 15 1912 月份不在有效值域1..12中WR4 6 -1 1912 日期不在有效值域1..31中WR5 6 32 1912 日期不在有效值域1..31中WR6 6 15 1811 年不在有效值域1812..2012中WR7 6 15 2013 年不在有效值域1812..2012中强健壮等价类测试用例集合:用例ID 月份日期年预期输出SR1 -1 15 1912 月份不在有效值域1..12中SR2 6 -1 1912 日期不在有效值域1..31中SR3 6 15 1811 年不在有效值域1812..2012中SR4 -1 -1 1912 月份不在有效值域1..12中日期不在有效值域1..31中SR5 6 -1 1811 日期不在有效值域1..31中年不在有效值域1812..2012中SR6 -1 15 1811 月份不在有效值域1..12中年不在有效值域1812..2012中SR7 -1 -1 1811 月份不在有效值域1..12中日期不在有效值域1..31中年不在有效值域1812..2012中。