Bootstrap

【软件测试】课程实验:实验二 黑盒测试实验一

一、实验目的

  1. 能熟练应用黑盒测试中的等价类划分方法设计测试用例;
  2. 能熟练应用黑盒测试中的边界值分析方法设计测试用例;
  3. 能数量综合使用等价类划分和边界值分析解决黑盒测试需求;

二、实验环境

  1. 硬件环境:PC 机一台
  2. 软件环境:Java 编程环境:Java SDK + Eclipse+junit5
  3. 待测程序: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 日。

要求

  1. 实现NextDate计算程序;
  2. 基于Junit,分别设计等价类划分及边界值测试用例;

实验过程注意事项

  1. 先利用等价类划分方法对输入/输出的取值进行规划,并设计相应测试用例;
  2. 进一步利用边界值分析对输入/输出取值边界进行彻底边界测试,作为等价类划分设计的测试用例的补充;这里的三个参数是相关的,边界值分析应采用边界条件的方法;
  3. 设计测试用例覆盖所有的等价类和各种边界情况;
  4. 等价类划分角度和结果并没有统一的答案,但都需要保证划分的合理性。

实验报告

一、NextDate问题的黑盒测试

NextDate程序中有3个输入,分别对应一个日期的年、月、日,程序能输出给定日期的下一天。程序能接收的日期输入范围为1582年1月1日到3000年12月31日。

要求:

  1. 实现NextDate计算
  2. 基于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. 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);
    }
}
;