程序说明:

前一日函数 Pre Date 是 NextDate的逆函数,即给定一 个月份、日期、年,会返回前一天的日期。
年的取值在1812年到2017年。
日的取值 在 1日到 31 日之间。
月的取值 在 1到 12 月之间
**

分析步骤:

**

一、决策表分析过程

1、条件桩、动作桩

输入:

–Year

–Month

–Day

为获得前一个日期,PreDate函数需执行的操作只有如下8种:

–day变量值减1

–day变量值复位为31

–day变量值复位为30

–day变量值复位为29

–day变量值复位为28

–month变量值减1

–month变量值复位为12

–year变量值减1

2、考虑规则个数

M1: {month:month有30天4月,6月,9月,11月,上月都是31天};
 M2: {month:month有31天,1月、3月、8月除外,5月,7月,10月,12月,上月都是30天};
 M3: {month:month是1月};
 M4: {month:month是2月};
 M5:{month:month是3月};
 M6:{month:month是8月};
 D1: {day:day=1};
 D2: {day:2≤day≤28};
 D3: {day:day=29};
 D4: {day:day=30};
 D5: {day:day=31};
 Y1: {year:year是闰年};
 Y2: {year:year不是闰年};

3、填入条件项和动作项

说明:符号“-”表示执行的动作与该条件的取值无关。

presto 日期类型 pre-date_决策表


presto 日期类型 pre-date_数据_02


presto 日期类型 pre-date_System_03


4、化简,决策表如下

presto 日期类型 pre-date_数据_04


二、根据简化后的决策表,可设计测试用例如下表所示:

presto 日期类型 pre-date_System_05


输出示例截图:

presto 日期类型 pre-date_决策表_06

三、实验总结
1、通过实践进行决策表测试的一般步骤:
第一步根据题意确定条件桩、动作桩;
第二步考虑规则个数,有n个条件的决策表有2n个规则(每个条件取真、假值);
第三步列出所有的条件桩和动作桩,向决策表填入条件项和动作项,得到初始决策表;
第四步化简决策表,若表中有两条以上规则具有相同的动作,并且在条件项之间存在极为相似的关系,便可以合并;
第五步设计测试用例。
2、求前一天日期不但要考虑到本月的天数还要考虑到上一个月的天数,因为要判断输入是否合法,所以我们把规则分析成D1: {day:day=1};D2: {day:2≤day≤28};D3: {day:day=29}; D4: {day:day=30}; D5: {day:day=31},而不是D1: {day:day=1};D2: {day:2≤day≤31}。另外尤其要区分平年与闰年。
3、通过决策表能够将复杂的问题按照各种可能的情况全部列举出来,简明并避免遗漏:利用决策表能够设计出完整的测试用例集合。运用决策表设计测试用例可以将条件理解为输入,将动作理解为输出。对于月份考虑规则的个数的时候,并非所有的31天的月份都在一起,在M2中的月份不但都是31天的月份,而且上个月都是30天,所以8月与M2不属于同一个规则。对于规则的划分首先根据题意来,然后再考虑所有情况,看到底如何设计以覆盖所有的输入输出情况,这里跟书本上求后一天案例是不同的。

四、源码

import java.util.Scanner;


public class PreDate {
	public static void main(String[] args){
		Scanner scancer=new Scanner(System.in);
		System.out.println("请输入年-月-日:");
		
		String s1 = scancer.nextLine();
		String[] s2 = s1.split("-");//将s1用逗号分隔,放到s2数组中
		int year = Integer.parseInt(s2[0]);//将字符串变成整数
		int month= Integer.parseInt(s2[1]);
		int day = Integer.parseInt(s2[2]);
		
//		int year=scancer.nextInt();
//		int month=scancer.nextInt();
//		int day=scancer.nextInt();
		//输入数据不合法
		if(year<1812||year>2017||month<1||month>12||day<1||day>31){
			System.out.println("输入的数据不符合设定");
			System.exit(0);
		}
		//判断日期是否符合现实
		switch(month){
		case 1:
		case 3:
		case 5:
		case 7:
		case 8:
		case 10:
		case 12:{
			if(day>=1&&day<=31)
				break;
			else if(day<1||day>31)
				System.out.println("输入的数据不符合设定");
			System.exit(0);

		}
		case 4:
		case 6:
		case 9:
		case 11:{
			if(day>=1&&day<=30)
				break;
			else
				System.out.println("输入的数据不符合设定");
			System.exit(0);
		}
		case 2:{
			if((year%400==0)||(year%4==0&&year%100!=0)){
				if(day>=1&&day<=29)
					break;	
				else
					System.out.println("输入的数据不符合设定");
				System.exit(0);
			}
			else if(day>=1&&day<=28)
				break;
			else
				System.out.println("输入的数据不符合设定");	
			System.exit(0);
		}	
		}
	//计算输入日期的前一个日期
	//当年份发生变化的情况
	if(month==1&&day==1){
		year=year-1;
		month=12;
		day=31;
	}
	//月份发生变化的情况
	else if(month!=1&&day==1){
		switch(month){
		case 2:
		case 4:
		case 6:
		case 8:
		case 9:
		case 11:{
			month=month-1;
			day=31;
			break;
		}
		case 5:
		case 7:
		case 10:
		case 12:{
		month=month-1;
		day=30;
		break;
		}
		case 3:{
			if((year%400==0)||(year%4==0&&year%100!=0)){
				month=month-1;
				day=29;
			}
			else{
				month=month-1;
				day=28;
			}
			break;
		}
	}	
	}
	//只有日期发生变化的情况
	else{
	day=day-1;
	}
	System.out.println("The PreDay is "+year+"-"+month+"-"+day);
}
}