2025/04/22

实验项目名称:实验一          

一、    实验目的

  1. 掌握黑盒测试的基础知识;
  2. 掌握黑盒测试的检查内容及测试目的;
  3. 掌握黑盒测试的几种基本测试方法:等价类划分方法、边界值分析方法、因果图法和决策表法;

二、  实验内容

1、 设计函数实现输入日期显示星期几,并用等价类及边界值法测试

2、 找零钱最佳组合:假设商店货品价格(R) 都不大于100元(且为整数),若顾客付款(P)在100元内,现有一个程序能在每位顾客付款后给出找零钱的最佳组合(找给顾客货币张数最少)。 假定此商店的货币面值只包括:50元(N50)、10元(N10)、 5元(N5)、1元(N1) 四种。请结合等价类划分法和边界值分析法为上述程序设计 出相应的测试用例。

3、 有一个饮料自动售货机(处理单价为5角钱)的控制处理软件,它的软件规格说明如下:若投入5角钱的硬币,按下“橙汁”或“啤酒”的按钮,则相应的饮料就送出来。若投入1元钱的硬币,同样也是按“橙汁”或“啤酒”的按钮,则自动售货机在送出相应饮料的同时退回5角钱的硬币。

4、 航空服务查询问题:根据航线,仓位,飞行时间查询航空服务。假设一个中国的航空公司规定:① 中国去欧美的航线所有座位都有食物供应,每个座位都可以播放电影。② 中国去非欧美的国外航线都有食物供应,只有商务仓可以播放电影。③ 中国国内的航班的商务仓有食物供应,但是不可以播放电影④ 中国国内航班的经济仓只有当飞行时间大于2小时时才有食物供应,但是不可以播放电影。请用程序实现上述功能,并用决策表法设计测试用例,再执行测试,撰写实验报告。

5、 旅馆住宿系统中,旅馆业主可进行添加房间操作。

–  旅馆业主登录旅馆住宿系统后,可以请求添加房间;

–  待进入“房间管理”对话框,单击“添加”按钮可进行添加房间操作;

–  添加房间时,可以设定房间的房间编号、房间类型、房间描述信息;

–  添加房间信息不能缺失,若某一项未填写,要给出提示信息;

–  房间编号长度不超过5个字符;

–  房间描述长度不超过1000个字符;

–  房间信息不能重复,成功填写后,可进行保存或取消操作,之后返回“房间管理”对话框,结束添加房间流程。

        实验步骤:

利用黑盒测试策略编写添加房间功能的测试用例。

三、  实验步骤及结果

实验步骤:

1、

①   设计程序

public class GetWeekday {

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        System.out.println("请输入一个日期(格式为yyyyMMdd):");

        String dateStr = scanner.nextLine();

        System.out.println(findWeekday(dateStr));

    }

    public static String findWeekday(String dateStr) {

        try {

 

            int year = Integer.parseInt(dateStr.substring(0, 4));

            int month = Integer.parseInt(dateStr.substring(4, 6));

            int day = Integer.parseInt(dateStr.substring(6));

            //不会判断二月是否有29、30、31要手动重新判断

            if (month == 2) {

                boolean isLeapYear = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);

                if (isLeapYear && day > 29) {

                    return "输入日期格式不正确,请输入正确的日期格式。";

                } else if (!isLeapYear && day > 28) {

                    return "输入日期格式不正确,请输入正确的日期格式。";

                }

            }

            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");

            LocalDate date = LocalDate.parse(dateStr, formatter);

 

            return date.getDayOfWeek().toString();

        } catch (DateTimeParseException e) {

            return "输入日期格式不正确,请输入正确的日期格式。";

        }

    }

}

②   划分等价类,得到等价类表。等价类表格式如下:

输入条件

有效等价类

唯一标识

无效等价类

唯一标识

1900到2050内的闰年

(1)

Year<1900

(10)

 

1900到2050内的平年

(2)

Year>2050

(11)

 

 

 

非数字

(12)

1、3、5、7、8、10、12

(3)

Month<1

(13)

 

4、6、9、11

(4)

Month>12

(14)

 

2

(5)

非数字

(15)

1-28

(6)

Day<1

(16)

 

29

(7)

Month=1,3,5,7,8,10,12时,Day>31

(17)

 

30

(8)

Month=4,6,9,11

时,Day>30

(18)

 

31

(9)

Year为平年,Month为2时,Day>28

(19)

 

 

 

Year为闰年,Month为2时,Day>29

(20)

 

 

 

非数字

(21)

 

③   运用等价类划分法设计测试用例,得到测试用例表。测试用例表格式如下:

 

序号

输入数据

覆盖等价类

输出

1

20000131

1、3、9

MONDAY

2

20010430

2、4、8

MONDAY

3

20000229

1、5、7

THUSDAY

4

20010228

2、5、6

WEDNESDAY

5

18990101

10、3、6

输入日期格式不正确,请输入正确的日期格式。

6

20510101

11、3、6

输入日期格式不正确,请输入正确的日期格式。

7

abcd0101

12、3、6

输入日期格式不正确,请输入正确的日期格式。

8

20000001

1、13、6

输入日期格式不正确,请输入正确的日期格式。

9

20001301

1、14、6

输入日期格式不正确,请输入正确的日期格式。

10

2000ab01

1、15、6

输入日期格式不正确,请输入正确的日期格式。

11

20000100

1、3、16

输入日期格式不正确,请输入正确的日期格式。

12

20000132

1、3、17

输入日期格式不正确,请输入正确的日期格式。

13

20000431

1、3、18

输入日期格式不正确,请输入正确的日期格式。

14

20010229

1、3、19

输入日期格式不正确,请输入正确的日期格式。

15

20000230

1、3、20

输入日期格式不正确,请输入正确的日期格式。

16

200001ab

1、3、21

输入日期格式不正确,请输入正确的日期格式。

 

④ 运用边界值法设计测试用例。

序号

输入数据

覆盖等价类

输出

1

19000101

1、3、6

MONDAY

2

19000228

2、5、6

WEDNESDAY

3

20000229

1、5、7

TUESDAY

4

20250430

2、4、8

WEDNESDAY

5

20250131

2、3、9

FRIDAY

6

18990101

10、3、6

输入日期格式不正确,请输入正确的日期格式。

7

20510101

11、3、6

输入日期格式不正确,请输入正确的日期格式。

8

abcd0101

12、3、6

输入日期格式不正确,请输入正确的日期格式。

9

20250001

13、2、6

输入日期格式不正确,请输入正确的日期格式。

10

20251301

14、2、6

输入日期格式不正确,请输入正确的日期格式。

11

2025ab01

15、2、6

输入日期格式不正确,请输入正确的日期格式。

12

20250100

16、2、3

输入日期格式不正确,请输入正确的日期格式。

13

20250132

17、2、3

输入日期格式不正确,请输入正确的日期格式。

14

20250431

18、2、4

输入日期格式不正确,请输入正确的日期格式。

15

19010229

19、2、5

输入日期格式不正确,请输入正确的日期格式。

16

20000230

20、1、5

输入日期格式不正确,请输入正确的日期格式。

17

202501ab

21、2、3

输入日期格式不正确,请输入正确的日期格式。

2、实验步骤:

①等价类表:

输入条件

有效等价类

唯一标识

无效等价类

唯一标识

货品价格

0<R<100

(1)

R=>100

(3)

 

R为整数

(2)

R<=0

(4)

 

 

 

R不为整数

(5)

付款

0<P<100

(6)

P>=100

(9)

 

P为整数

(7)

P<=0

(10)

 

P>=R

(8)

P不为整数

(11)

 

 

 

R>P

(12)

②运用等价类划分法设计测试用例

序号

输入数据

覆盖等价类

输出

1

(50, 60)

(1)(2)(6)(7)(8)

找零组合如下:
50 元: 0 张
10 元: 1 张
5 元: 0 张
1 元: 0 张

2

(100, 99)

(3)(2)(6)(7)(8)

输入有误,请检查货品价格和付款金额。

3

(-10, 50)

(4)(2)(6)(7)(8)

输入有误,请检查货品价格和付款金额。

4

(50.5, 60)

(5)(1)(6)(7)(8)

输入有误,请检查货品价格和付款金额。

5

(50, 100)

(9)(1)(2)(7)(8)

输入有误,请检查货品价格和付款金额。

6

(50, -10)

(10)(1)(2)(7)(8)

输入有误,请检查货品价格和付款金额。

7

(50, 50.5)

(11)(1)(2)(6)(8)

输入有误,请检查货品价格和付款金额。

8

(50, 49)

(12)(1)(2)(6)(7)

输入有误,请检查货品价格和付款金额。

③运用边界值法设计测试用例。

序号

输入数据

覆盖等价类

输出

1

(1, 1)

R 最小值,P = R

找零组合如下:

50 元: 0 张

10 元: 0 张

5 元: 0 张

1 元: 0 张

2

(1, 2)

R 最小值,P 稍大于 R

找零组合如下:

50 元: 0 张

10 元: 0 张

5 元: 0 张

1 元: 1 张

3

(99, 99)

R 最大值,P = R

找零组合如下:

50 元: 0 张

10 元: 0 张

5 元: 0 张

1 元: 0 张

4

(99, 100)

R 最大值,P 刚好能覆盖找零

找零组合如下:

50 元: 0 张

10 元: 0 张

5 元: 0 张

1 元: 1 张

5

(0, 1)

R 边界外最小值,无效情况

输入有误,请检查货品价格和付款金额。

6

(100, 101)

R 边界外最大值,P 边界外值,无效情况

输入有误,请检查货品价格和付款金额。

7

(1, 0)

P 边界外最小值,无效情况

输入有误,请检查货品价格和付款金额。

8

(1, 100)

P 边界值,无效情况

输入有误,请检查货品价格和付款金额。

④设计程序

public class Change {

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        try {

            System.out.print("请输入货品价格 (R <= 100): ");

            int R = scanner.nextInt();

            System.out.print("请输入顾客付款金额 (P <= 100): ");

            int P = scanner.nextInt();

 

            if (R >= 100 || P >= 100 || P < R || R <= 0 || P <= 0)  {

                System.out.println("输入有误,请检查货品价格和付款金额。");

            } else {

                int change = P - R;

                int N50 = change / 50;

                change %= 50;

                int N10 = change / 10;

                change %= 10;

                int N5 = change / 5;

                change %= 5;

                int N1 = change;

 

                System.out.println("找零组合如下:");

                System.out.println("50 元: " + N50 + " 张");

                System.out.println("10 元: " + N10 + " 张");

                System.out.println("5 元: " + N5 + " 张");

                System.out.println("1 元: " + N1 + " 张");

            }

        }catch (Exception e)

        {

            System.out.println("输入有误,请检查货品价格和付款金额。");

        }

    }

}

3、实验步骤:

        ①编写程序

        public class VendingMachineGUI extends JFrame {

    private ButtonGroup coinGroup;

    private ButtonGroup drinkGroup;

    private JButton purchaseButton;

    private JLabel resultLabel;

 

    public VendingMachineGUI() {

        setTitle("饮料自动售货机");

        setSize(350, 350);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setLayout(new BorderLayout());

 

        // 主面板,使用 GridLayout 布局

        JPanel mainPanel = new JPanel(new GridLayout(4, 1, 10, 10));

        mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

 

        // 投币选择部分

        JLabel coinLabel = new JLabel("请投币:");

        coinGroup = new ButtonGroup();

        JRadioButton fiftyCent = new JRadioButton("五角");

        JRadioButton oneDollar = new JRadioButton("一元");

        coinGroup.add(fiftyCent);

        coinGroup.add(oneDollar);

 

        JPanel coinPanel = new JPanel();

        coinPanel.add(coinLabel);

        coinPanel.add(fiftyCent);

        coinPanel.add(oneDollar);

        mainPanel.add(coinPanel);

 

        // 饮料选择部分

        JLabel drinkLabel = new JLabel("请选择饮料:");

        drinkGroup = new ButtonGroup();

        JRadioButton orangeJuice = new JRadioButton("橙汁");

        JRadioButton beer = new JRadioButton("啤酒");

        drinkGroup.add(orangeJuice);

        drinkGroup.add(beer);

 

        JPanel drinkPanel = new JPanel();

        drinkPanel.add(drinkLabel);

        drinkPanel.add(orangeJuice);

        drinkPanel.add(beer);

        mainPanel.add(drinkPanel);

 

        // 购买按钮面板

        JPanel buttonPanel = new JPanel();

        purchaseButton = new JButton("购买");

        buttonPanel.add(purchaseButton);

        mainPanel.add(buttonPanel);

 

        // 结果显示标签面板

        JPanel resultPanel = new JPanel();

        resultLabel = new JLabel("");

        resultPanel.add(resultLabel);

        mainPanel.add(resultPanel);

 

        add(mainPanel, BorderLayout.CENTER);

 

        // 为购买按钮添加点击事件监听器

        purchaseButton.addActionListener(new ActionListener() {

            @Override

            public void actionPerformed(ActionEvent e) {

                String coin = "";

                if (fiftyCent.isSelected()) {

                    coin = "五角";

                } else if (oneDollar.isSelected()) {

                    coin = "一元";

                }

 

                String drink = "";

                if (orangeJuice.isSelected()) {

                    drink = "橙汁";

                } else if (beer.isSelected()) {

                    drink = "啤酒";

                }

 

                String result;

                if (coin.equals("五角")) {

                    result = "已为您送出 " + drink + "。";

                } else if (coin.equals("一元")) {

                    result = "已为您送出 " + drink + ",并退回五角硬币。";

                } else {

                    result = "请选择投币金额。";

                }

                resultLabel.setText(result);

            }

        });

    }

 

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            @Override

            public void run() {

                VendingMachineGUI vendingMachine = new VendingMachineGUI();

                vendingMachine.setVisible(true);

            }

        });

    }

}

        ②分析原因与结果

        原因(输入条件)

C1:投入 5 角硬币

C2:投入 1 元硬币

C3:按下 “橙汁” 按钮

C4:按下 “啤酒” 按钮

结果(输出动作)

E1:送出橙汁饮料

E2:送出啤酒饮料

E3:退回 5 角硬币

④   画出因果图

 

        ④转化为决策表

规则编号

C1 投入 5 角硬币

C2 投入 1 元硬币

C3 按下 “橙汁” 按钮

C4 按下 “啤酒” 按钮

E1 送出橙汁饮料

E2 送出啤酒饮料

E3 退回 5 角硬币

1

1

0

1

0

1

0

0

2

1

0

0

1

0

1

0

3

0

1

1

0

1

0

1

4

0

1

0

1

0

1

1

5

0

0

1

0

0

0

0

6

0

0

0

1

0

0

0

7

1

1

-

-

-

-

-

8

-

-

0

0

0

0

0

 

        ⑤根据决策表设计测试用例,得到测试用例表

       

用例编号

输入(投入硬币、按下按钮)

预期输出(送出饮料、退回硬币)

1

投入 5 角,按下 “橙汁” 按钮

送出橙汁饮料,无退回硬币

2

投入 5 角,按下 “啤酒” 按钮

送出啤酒饮料,无退回硬币

3

投入 1 元,按下 “橙汁” 按钮

送出橙汁饮料,退回 5 角硬币

4

投入 1 元,按下 “啤酒” 按钮

送出啤酒饮料,退回 5 角硬币

5

不投入硬币,按下 “橙汁” 按钮

无饮料送出,无退回硬币

6

不投入硬币,按下 “啤酒” 按钮

无饮料送出,无退回硬币

7

投入 5 角和 1 元(异常)

提示错误信息

8

投入硬币,不按任何按钮

无饮料送出,无退回硬币

4、实验步骤:

      ① 编写程序

      public class AirlineServiceQuery extends JFrame {

    private JRadioButton routeToEuropeAmerica;

    private JRadioButton routeToOtherForeign;

    private JRadioButton routeDomestic;

    private JRadioButton classBusiness;

    private JRadioButton classEconomy;

    private JRadioButton flightTimeOver2Hours;

    private JRadioButton flightTimeUnder2Hours;

    private JButton queryButton;

    private JTextArea resultArea;

 

    public AirlineServiceQuery() {

        setTitle("航空公司服务查询");

        setSize(400, 400);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setLayout(new FlowLayout());

 

        // 航线选择

        ButtonGroup routeGroup = new ButtonGroup();

        routeToEuropeAmerica = new JRadioButton("中国去欧美的航线");

        routeToOtherForeign = new JRadioButton("中国去非欧美的国外航线");

        routeDomestic = new JRadioButton("中国国内的航班");

        routeGroup.add(routeToEuropeAmerica);

        routeGroup.add(routeToOtherForeign);

        routeGroup.add(routeDomestic);

 

        // 仓位选择

        ButtonGroup classGroup = new ButtonGroup();

        classBusiness = new JRadioButton("商务仓");

        classEconomy = new JRadioButton("经济仓");

        classGroup.add(classBusiness);

        classGroup.add(classEconomy);

 

        // 飞行时间选择

        ButtonGroup flightTimeGroup = new ButtonGroup();

        flightTimeOver2Hours = new JRadioButton("飞行时间大于2小时");

        flightTimeUnder2Hours = new JRadioButton("飞行时间小于等于2小时");

        flightTimeGroup.add(flightTimeOver2Hours);

        flightTimeGroup.add(flightTimeUnder2Hours);

 

        // 查询按钮

        queryButton = new JButton("查询");

        queryButton.addActionListener(new QueryButtonListener());

 

        // 结果显示区域

        resultArea = new JTextArea(10, 30);

        resultArea.setEditable(false);

 

        // 添加组件到窗口

        add(routeToEuropeAmerica);

        add(routeToOtherForeign);

        add(routeDomestic);

        add(classBusiness);

        add(classEconomy);

        add(flightTimeOver2Hours);

        add(flightTimeUnder2Hours);

        add(queryButton);

        add(new JScrollPane(resultArea));

    }

 

    private class QueryButtonListener implements ActionListener {

        @Override

        public void actionPerformed(ActionEvent e) {

            boolean hasFood = false;

            boolean canPlayMovie = false;

 

            if (routeToEuropeAmerica.isSelected()) {

                hasFood = true;

                canPlayMovie = true;

            } else if (routeToOtherForeign.isSelected()) {

                hasFood = true;

                canPlayMovie = classBusiness.isSelected();

            } else if (routeDomestic.isSelected()) {

                if (classBusiness.isSelected()) {

                    hasFood = true;

                    canPlayMovie = false;

                } else if (classEconomy.isSelected()) {

                    hasFood = flightTimeOver2Hours.isSelected();

                    canPlayMovie = false;

                }

            }

 

            String result = "食物供应: " + (hasFood ? "有" : "无") + "\n";

            result += "电影播放: " + (canPlayMovie ? "可以" : "不可以");

            resultArea.setText(result);

        }

    }

 

    public static void main(String[] args) {

        SwingUtilities.invokeLater(() -> {

            AirlineServiceQuery query = new AirlineServiceQuery();

            query.setVisible(true);

        });

    }

}

② 构造决策表

条件:

C1:航线是否为中国去欧美的航线

C2:航线是否为中国去非欧美的国外航线

C3:航线是否为中国国内航班

C4:仓位是否为商务仓

C5:飞行时间是否大于 2 小时

动作:

A1:有食物供应

A2:可以播放电影

规则编号

C1

C2

C3

C4

C5

A1

A2

1

Y

N

N

-

-

Y

Y

2

N

Y

N

Y

-

Y

Y

3

N

Y

N

N

-

Y

N

4

N

N

Y

Y

-

Y

N

5

N

N

Y

N

Y

Y

N

6

N

N

Y

N

N

N

N

③ 根据决策表设计测试用例,得到测试用例表

用例编号

航线

仓位

飞行时间

预期结果(食物供应)

预期结果(电影播放)

1

中国去欧美的航线

任意

任意

可以

2

中国去非欧美的国外航线

商务仓

任意

可以

3

中国去非欧美的国外航线

经济仓

任意

不可以

4

中国国内航班

商务仓

任意

不可以

5

中国国内航班

经济仓

大于 2 小时

不可以

6

中国国内航班

经济仓

小于等于 2 小时

不可以

5、

等价类划分

输入条件

有效等价类

无效等价类

房间编号

 

 

房间编号必填

填写合法编号(如:A001)

不填写(空)

编号长度≤5 字符

1-5 个字符

6 个及以上字符

编号唯一性

未注册过的编号

已注册过的编号

字符类型

纯数字 / 字母

含特殊符号

房间类型

 

 

房间类型必填

填写合法类型

不填写

类型枚举

系统允许的类型

非法类型

房间描述

 

 

房间描述必填

填写合法描述

不填写

描述长度≤1000 字符

1-1000 个字符

1001 个及以上字符

边界值分析

1房间编号长度边界

边界点:5(有效最大值)、6(无效最小值)

测试用例:

有效边界:编号为ABCDE(5 个字符),验证是否允许保存。

无效边界:编号为ABCDEF(6 个字符),验证是否提示 “长度超过限制”。

2房间描述长度边界

边界点:1000(有效最大值)、1001(无效最小值)

测试用例:

有效边界:描述为重复a字符 1000 次,验证是否允许保存。

无效边界:描述为重复a字符 1001 次,验证是否提示 “长度超过限制”。

测试用例设计(结合等价类与边界值)

用例编号

测试场景

输入数据

预期结果

1

有效编号(5 字符)、有效类型、有效描述

编号:A0001(5 字符)

类型:单人间
描述:正常描述(10 字符)

保存成功

2

编号为空(必填项)

编号:空

类型:单人间

描述:正常描述

提示 “房间编号不能为空”。

3

编号 6 字符(超长)

编号:A00001(6 字符)

类型:单人间

描述:正常描述

提示 “房间编号长度不能超过 5 个字符”。

4

重复编号(唯一性)

编号:A001(已存在)

类型:单人间

描述:新描述

提示 “房间信息已存在,不能重复添加”。

5

描述 1000 字符(边界值)

描述:重复a字符 1000 次

保存成功。

6

描述 1001 字符(超边界)

描述:重复a字符 1001 次

提示 “房间描述长度不能超过 1000 个字符”。

7

类型为空(必填项)

编号:A002

类型:空

描述:正常描述

提示 “房间类型不能为空”。

8

编号含特殊符号(非法字符)

编号:A#001

类型:单人间

描述:含符号

若系统限制纯数字 / 字母,提示错误;若允许符号则保存成功(需根据需求调整)。

9

类型为空(必填项)

编号:A002

类型:单人间

描述:空

提示 “房间描述不能为空”。

posted @ 2025-04-22 08:15  伐木工熊大  阅读(5)  评论(0)    收藏  举报