一、实验目的
- 能熟练应用黑盒测试中的等价类划分方法设计测试用例;
- 能熟练应用黑盒测试中的边界值分析方法设计测试用例;
- 能数量综合使用等价类划分和边界值分析解决黑盒测试需求;
二、实验环境
- 硬件环境:PC 机一台
- 软件环境:Java 编程环境:Java SDK + Eclipse+junit5
- 待测程序:NextDate(可执行文件),JunitBMI健康值计算判断程序
三、实验内容与步骤
实验一:NextDate问题的黑盒测试
实验背景
日期是软件中被频繁处理的信息之一,软件开发人员有必要了解的一些公历历法的相关知识。
公历的前身是古罗马凯撒修订的儒略历。 根据儒略历的规定,每 4 年有 1 个闰年,闰年为 366 日,其余 3 年(称 为平年)各有 365 日。公元年数能被 4 除得尽的是闰年。儒略历 1 年平均长 365.25 日,比实际公转周期的 365.2422 日长 11 分 14 秒,即每 400 年约长 3 日。这样到公元 16 世纪时已经积累了有 10 天误差。可以明显感觉到两至两分 提 前了。在此情况下,教皇格列高里十三世于 1582 年宣布改历。先是一步到位把儒略历 1582 年 10 月 4 日的下一 天定为格列历 10 月 15 日,中间跳过 10 天。同时修改了儒略历置闰法则。除了保留儒略历年数被 4 除尽的是闰年 外。增加了被 100 除得尽而被 400 除不尽的则不是闰年的规定。这样的做法可在 400 年中减少 3 个闰年。在格列高 里历历法里,400 年中有 97 个闰年(每年 366 日)及 303 个平年(每年 365 日),所以每年平均长 365.2425 日,与 公 转周期的 365.2422 日十分接近。可基本保证到公元 5000 年前误差不超过 1 天。
在软件开发和测试中,我们需要注意以下的一些有用信息:
- 1582 年 10 月 5 日至 10 月 14 日排除在公历外
- 2038 年 1 月 19 日是 BIOS 提供的记时基准时间 1970 年 1 月 1 日的最大值(下一个千年虫问题的根源) l 英国 1752 年才采用阳历,他们扣除 9/3/1752 到 9/13/1752 年同步以月亮为参照的立法
注意,以上信息中,后两条并不影响我们所进行的测试活动,可不用考虑。
NextDate 程序中有 3 个输入,分别对应一个日期的年、月、日,程序能输出给定日期的下一天。 程序能接收的日期输入范围为 1582 年 1 月 1 日到 3000 年 12 月 31 日。
要求
- 实现NextDate计算程序;
- 基于Junit,分别设计等价类划分及边界值测试用例;
实验过程注意事项
- 先利用等价类划分方法对输入/输出的取值进行规划,并设计相应测试用例;
- 进一步利用边界值分析对输入/输出取值边界进行彻底边界测试,作为等价类划分设计的测试用例的补充;这里的三个参数是相关的,边界值分析应采用边界条件的方法;
- 设计测试用例覆盖所有的等价类和各种边界情况;
- 等价类划分角度和结果并没有统一的答案,但都需要保证划分的合理性。
实验报告
一、NextDate问题的黑盒测试
NextDate程序中有3个输入,分别对应一个日期的年、月、日,程序能输出给定日期的下一天。程序能接收的日期输入范围为1582年1月1日到3000年12月31日。
要求:
- 实现NextDate计算
- 基于Junit,分别设计等价类划分及边界值测试用例。
1.1 测试用例设计
1.1.1 等价类划分
1、有效输入等价类
年 | 月 | 日 | 预测值 |
1582 | 4 | 18 | 15820419 |
2024 | 3 | 29 | 20240401 |
2024 | 5 | 28 | 20240529 |
3000 | 12 | 31 | 30010101 |
2、无效输入等价类
年 | 月 | 日 | 预测值 |
1581 | 4 | 18 | Year is not in the range |
3250 | 4 | 18 | Year is not in the range |
2024 | -1 | 18 | Mouth is not in the range |
2024 | 13 | 18 | Mouth is not in the range |
2024 | 4 | -1 | Day is not in the range |
2024 | 4 | 35 | Day is not in the range |
2024 | 4 | 30 | Day is not in the range |
2024 | 1% | 18 | Illegal input date! |
2024 | 4 | 1% | Illegal input date! |
202% | 4 | 18 | Illegal input date! |
3、闰年等价类
年 | 月 | 日 | 预测值 |
1584 | 2 | 28 | 15840301 |
1584 | 2 | 29 | 15840301 |
2000 | 2 | 28 | 20000229 |
2000 | 2 | 29 | 20000301 |
4、平年等价类
年 | 月 | 日 | 预测值 |
1582 | 2 | 28 | 15820301 |
1583 | 2 | 28 | 15830301 |
2001 | 2 | 28 | 20000301 |
2300 | 2 | 28 | 23000301 |
1.1.2 边界值法
年的取值在[1582,3000]之间。月的取值在[1,12]之间。日的取值范围,对于1,3,5,7,8,10,12月为[1,31];对于4,6,9,11月为[1,30];对于2月还要区分是闰年还是平年,闰年2月29天,平年2月28天。
边界值包括最小值、最大值、平年闰年边界、年月日更替边界、异常临界值等,具体测试用例如下表所示。
年 | 月 | 日 | 预测值 |
1581 | 4 | 18 | Year is not in the range |
1999 | 12 | 31 | 20000101 |
2999 | 12 | 31 | 30000101 |
3001 | 4 | 18 | Year is not in the range |
2024 | 0 | 18 | Mouth is not in the range |
2024 | 4 | 18 | 20240419 |
2024 | 12 | 18 | 20241219 |
2024 | 13 | 18 | Mouth is not in the range |
2024 | 4 | 0 | Day is not in the range |
2024 | 4 | 18 | 20240419 |
2024 | 3 | 29 | 20240401 |
2024 | 3 | 30 | Day is not in the range |
2024 | 4 | 50 | Day is not in the range |
1.2 测试结果
- 1、NextDate程序计算下一天的主要代码见NextDate.java文件。
2、3、有效等价类测试结果如下图所示。(源程序:DateTest.java)
3、无效等价类测试结果如下图所示。(源程序:DateIllegalTest.java)
4、边界值测试结果如下图所示。(源程序:DateBoundaryTest.java)
二、实验结果与分析
通过这次实验,更加深入了解黑盒测试原理,了解等价类划分和边界值划分规则,以及测试方法的应用。
程序代码
NextDate.java
package course2;
import java.util.regex.Pattern;
public class NextDate {
public static String nextDate(Integer y, Integer m, Integer d) {
int year, month, day;
year = y;
month = m;
day = d;
String result = new String();
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) {
System.out.println("Illegal input date!");
} else
day = day + 1;
break;
case 12:
if (day == 31) {
day = 1;
month = 1;
year = year + 1;
} else if (day < 31) {
day = day + 1;
}
break;
case 2: {
if (day == 28)
if (((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)) {
day = 29;
} else {
day = 1;
month = 3;
}
else if (day == 29) {
day = 1;
month = 3;
} else if (day < 28) {
day = day + 1;
} else {
result = "Illegal input date!";
}
}
break;
default:
}
if (year >= 1582 && year <= 3000 && month <= 12 && month >= 1
&& day <= 31 && day >= 1) {
StringBuilder months = new StringBuilder();
StringBuilder days = new StringBuilder();
if (month < 10)
months = months.append(0).append(month);
else
months = months.append(month);
if (day < 10)
days = days.append(0).append(day);
else
days = days.append(day);
StringBuilder resultB = new StringBuilder().append(year).append(months).append(days);
result = resultB.toString();
} else if (year < 1582 || year > 3000) {
result = "Year is not in the range";
} else if (month > 12 || month < 1) {
result = "Mouth is not in the range";
} else if (day > 31 || day < 1) {
result = "Day is not in the range";
} else result = null;
return result;
}
}
DateTests.java
package course2;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
import java.util.Collection;
@RunWith(Parameterized.class)
public class DateTests {
private Integer year;
private Integer mouth;
private Integer day;
private String expected;
@Parameterized.Parameters(name = "{0}.{1}.{2} expected:{3}")
public static Collection<?> prepareData(){
Object [][] object = {
//effective use cases
{2024, 4, 18, "20240419"},
{2024, 3, 29, "20240401"},
{2024, 2, 28, "20240229"},
{2023, 12, 31, "20240101"},
};
return Arrays.asList(object);
}
public DateTests(Integer year,Integer mouth,Integer day,String expected){
this.year = year;
this.mouth = mouth;
this.day = day;
this.expected = expected;
}
@Test
public void testDate(){
String result = NextDate.nextDate(year,mouth,day);
Assert.assertEquals(expected,result);
}
}
DateIllegalTests.java
package course2;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
import java.util.Collection;
@RunWith(Parameterized.class)
public class DateIllegalTests {
private Integer year;
private Integer mouth;
private Integer day;
private String expected;
@Parameterized.Parameters(name = "{0}.{1}.{2} expected:{3}")
public static Collection<?> prepareData(){
Object [][] object = {
//year is not in the range
{1581, 4, 18, "Year is not in the range"},
{3250, 4, 18, "Year is not in the range"},
//mouth is not in the range
{2024, -1, 18, "Mouth is not in the range"},
{2024, 13, 18, "Mouth is not in the range"},
//day is not in the range
{2024, 4, 35, "Day is not in the range"},
{2024, 3, 30, "Day is not in the range"},
{2024, 4, -1, "Day is not in the range"},
//Illegal input date!
{"202%", 4, 18, "Illegal input date!"},
{2024, "1%", 18, "Illegal input date!"},
{2024, 4, "1%", "Illegal input date!"},
};
return Arrays.asList(object);
}
public DateIllegalTests(Integer year, Integer mouth, Integer day, String expected){
this.year = year;
this.mouth = mouth;
this.day = day;
this.expected = expected;
}
@Test
public void testDate(){
String result = NextDate.nextDate(year,mouth,day);
Assert.assertEquals(expected,result);
}
}
DateBoundaryTests.java
package course2;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
import java.util.Collection;
@RunWith(Parameterized.class)
public class DateBoundaryTests {
private int year;
private int mouth;
private int day;
private String expected;
@Parameterized.Parameters(name = "{0}.{1}.{2} expected:{3}")
public static Collection<?> prepareData(){
Object [][] object = {
//year
{1581, 4, 18, "Year is not in the range"},
{1999, 12, 31, "200000101"},
{2999, 12, 31, "300000101"},
{3001, 4, 18, "Year is not in the range"},
//mouth
{2024, 0, 18, "Mouth is not in the range"},
{2024, 4, 18, "20240419"},
{2024, 12, 18, "20241219"},
{2024, 13, 18, "Mouth is not in the range"},
//day
{2024, 4, 0, "Day is not in the range"},
{2024, 4, 18, "20240419"},
{2024, 3, 29, "20240401"},
{2024, 3, 30, "Day is not in the range"},
{2024, 4, 50, "Day is not in the range"},
};
return Arrays.asList(object);
}
public DateBoundaryTests(int year,int mouth,int day,String expected){
this.year = year;
this.mouth = mouth;
this.day = day;
this.expected = expected;
}
@Test
public void testDate(){
String result = NextDate.nextDate(year,mouth,day);
Assert.assertEquals(expected, result);
}
}