实验项目名称:黑盒测试
一、实验目的
1、 掌握黑盒测试的基础知识;
2、 掌握黑盒测试的检查内容及测试目的;
3、 掌握黑盒测试的几种基本测试方法:等价类划分方法、边界值分析方法、因果图法和决策表法;
二、实验要求
1、 复习有关内容,理解黑盒测试;
2、 掌握等价类划分、边界值分析方法、因果图法和决策表法,并能设计出测试用例;
3、 对具体软件,能分别使用相应的黑盒测试方法设计测试用例,并实施测试、分析测试结果。
三、实验内容
1、设计函数实现输入日期显示星期几,并用等价类及边界值法测试
实验步骤:
① 设计程序
② 划分等价类,得到等价类表。等价类表格式如下:
输入条件 |
有效等价类 |
唯一标识 |
无效等价类 |
唯一标识 |
… |
… |
… |
… |
… |
… |
… |
… |
… |
… |
③ 运用等价类划分法设计测试用例,得到测试用例表。测试用例表格式如下:
序号 |
输入数据 |
覆盖等价类 |
输出 |
|
|
|
|
④ 运用边界值法设计测试用例。
(1)程序设计
package cn.yjw.com; import java.util.Scanner; public class Data { public static int which_week(int y, int m, int d){//年、月、日 int w = ((d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) % 7) +1;//余数为:0、1、2、3、4、5、6 return w; } public static void main(String[] args) { int year,month,day; Scanner scanner = new Scanner(System.in); System.out.println("请输入年"); try { year = scanner.nextInt(); } catch (Exception e){ System.out.println("输入年份无效"); return; } System.out.println("请输入月"); try { month = scanner.nextInt(); } catch (Exception e){ System.out.println("输入月份无效"); return; } System.out.println("请输入日"); try { day = scanner.nextInt(); } catch (Exception e){ System.out.println("输入日期无效"); return; } if (year <= 1900 || year >= 2060){//1900年1月1日正好是星期1 System.out.println("输入年份无效"); return; } if (month < 1 || month > 12){ System.out.println("输入月份无效"); return; } if (day < 1 || day > 31){ System.out.println("输入日期无效"); return; } if (year % 4 == 0 && month == 2 && day > 29){//闰年 System.out.println("输入日期无效"); return; } if (year % 4 != 0 && month == 2 && day > 28){//平年 System.out.println("输入日期无效"); return; } if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12){ if (day >31){ System.out.println("输入日期无效"); return; } } if (month == 4 || month == 6 || month == 9 || month == 11){ if (day > 30) { System.out.println("输入日期无效"); return; } } int week = which_week(year,month,day); System.out.println("星期"+week); } }
(2)划分等价类,得到等价类表。
输入条件 |
有效等价类 |
唯一标识 |
无效等价类 |
唯一标识 |
Year |
1900<=Year<=2060的闰年 |
1 |
Year<1900 |
3 |
1900<=Year<=2060的平年 |
2 |
Year>2060 |
4 |
|
|
|
非数字 |
5 |
|
Month |
1、3、5、7、8、10、12 |
6 |
Month>12 |
9 |
2 |
7 |
Month<1 |
10 |
|
4、6、9、11 |
8 |
非数字 |
11 |
|
Day |
1-28 |
12 |
Day>31 |
16 |
29 |
13 |
Day<1 |
17 |
|
30 |
14 |
Year为闰年且Month为2时,Day>29 |
18 |
|
31 |
15 |
Year为平年且Month为2时,Day>28 |
19 |
|
|
|
Month=1,3,5,7,8,10,12时,Day>31 |
20 |
|
|
|
Month=4,6,9,11 时,Day>30 |
21 |
|
|
|
非数字 |
22 |
(3)运用等价类划分法设计测试用例,得到测试用例表
序号 |
输入数据 |
覆盖等价类 |
输出 |
1 |
2000.1.28 |
1、6、12 |
星期4 |
2 |
2000.2.28 |
1、7、12 |
星期6 |
3 |
2000.4.28 |
1、8、12 |
星期5 |
4 |
1999.1.28 |
2、6、12 |
星期2 |
5 |
1999.2.28 |
2、7、12 |
星期4 |
6 |
1999.4.28 |
2、8、12 |
星期3 |
7 |
2000.3.32 |
1、6、16 |
输入日期无效 |
8 |
2000.5.0 |
1、6、17 |
输入日期无效 |
9 |
2000.5.33 |
1、6、20 |
输入日期无效 |
10 |
2000.2.30 |
1、7、18 |
输入日期无效 |
11 |
2000.4.31 |
1、8、21 |
输入日期无效 |
12 |
呜呜呜 |
5 |
输入年份无效 |
13 |
2000.呜呜 |
1、11 |
输入月份无效 |
14 |
2000.7.无 |
1、6、22 |
输入日期无效 |
15 |
2000.13.10 |
1、9、12 |
输入月份无效 |
16 |
1999.2.29 |
2、7、19 |
输入日期无效 |
17 |
2000.6.0 |
1、8、17 |
输入日期无效 |
(4)边界值测试
年份:00000000 输入错误
月份:20230101 20231231 周日 周日
31天月份边界值:20220101 20220131 周六 周一
20220102 20220130 周日 周日
20220100 20220132 输入错误 输入错误
30天月份边界值:20220430 20220401 周六 周五
20220429 20220402 周五 周六
20220431 20220400 输入错误 输入错误
29天月份边界值:20200229 20200201 周六 周六
20200228 20200202 周五 周日
20200230 20200200 输入错误 输入错误
28天月份边界值:20210228 20210201 周日 周一
20210227 20200202 周六 周二
20210229 20200200 输入错误 输入错误
2、找零钱最佳组合
假设商店货品价格(R) 都不大于100元(且为整数),若顾客付款(P)在100元内,现有一个程序能在每位顾客付款后给出找零钱的最佳组合(找给顾客货币张数最少)。 假定此商店的货币面值只包括:50元(N50)、10元(N10)、 5元(N5)、1元(N1) 四种。
请结合等价类划分法和边界值分析法为上述程序设计 出相应的测试用例。
实验步骤:
同上题
(1)程序设计
package cn.yjw.com; import java.util.Scanner; public class PayBack { public static void main(String[] args) { int N50 = 0,N10 = 0,N5 = 0,N1=0; double price,pay,value; Scanner scanner = new Scanner(System.in); System.out.println("请输入商品价格"); try { price = scanner.nextDouble(); } catch (Exception e){ System.out.println("输入价格无效"); return; } System.out.println("请输入顾客支付金额"); try { pay = scanner.nextDouble(); } catch (Exception e){ System.out.println("输入支付金额无效"); return; } if (price > pay){ System.out.println("无效,顾客付款小于商品价格"); return; } if ( price>100 || pay > 100 || pay < 0 || price < 0){ System.out.println("无效输入"); return; } else { value = pay - price; if (value / 50 >= 1){ N50 = (int) (value / 50); value = value - 50 * N50; } if (value / 10 >= 1){ N10 = (int) (value / 10); value = value - 10 * N10; } if (value / 5 >= 1){ N5 = (int) (value / 5); value = value - 5 * N5; } N1 = (int) (value); } System.out.println("1元" + N1 + "张"); System.out.println("5元" + N5 + "张"); System.out.println("10元" + N10 + "张"); System.out.println("50元" + N50 + "张"); } }
(2)划分等价类,得到等价类表。
输入条件 |
有效等价类 |
唯一标识 |
无效等价类 |
唯一标识 |
商品价格 |
0<=R<=100 |
1 |
R<O或R>100 |
3 |
|
|
R非数字 |
4 |
|
顾客付款 |
0<=P<=100 |
2 |
P>100或P<0 |
5 |
|
|
P非数字 |
6 |
|
|
|
R>P |
7 |
(3)运用等价类划分法设计测试用例,得到测试用例表
序号 |
输入数据 |
覆盖等价类 |
输出 |
1 |
R=60,P=80 |
1、2 |
10元两张 |
2 |
R=A,P=10 |
4、2 |
输入价格无效 |
3 |
R=10,P=A |
1、6 |
输入支付金额无效 |
4 |
R=75,P=40 |
1、7 |
无效,顾客付款小于商品价格 |
5 |
R=60,P=102 |
1、5 |
输入支付金额无效 |
6 |
R=101,P=80 |
2、3 |
输入价格无效 |
(4)边界值
序号 |
输入数据 |
覆盖等价类 |
输出 |
1 |
R=99,P=100 |
1、2 |
1元一张 |
2 |
R=101,P=102 |
3、5 |
无效输入 |
3 |
R=-1,P=1 |
2、3 |
无效输入 |
3、有一个饮料自动售货机(处理单价为5角钱)的控制处理软件,它的软件规格说明如下:
若投入5角钱的硬币,按下“橙汁”或“啤酒”的按钮,则相应的饮料就送出来。若投入1元钱的硬币,同样也是按“橙汁”或“啤酒”的按钮,则自动售货机在送出相应饮料的同时退回5角钱的硬币。
模拟程序如下:
package cn.yjw.com; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; public class VendingMachine extends JFrame { private static JPanel jp1; private static JPanel jp2; private static JPanel jp3; private static JPanel jp4; private static JLabel jlb1; private static JLabel jlb2; private static JLabel jlb3; private static JLabel jlb4; private static JLabel jlb5; private static JLabel jlb6; private static JRadioButton jrb1; private static JRadioButton jrb2; private static JRadioButton jrb3; private static JRadioButton jrb4; private static JButton jb1; private static JButton jb2; private static double money; private static String info; public static void main(String[] args) { VendingMachine frame = new VendingMachine(); frame.setVisible(true); } public VendingMachine(){ jp1 = new JPanel(); jp2 = new JPanel(); jp3 = new JPanel(); jp4 = new JPanel(); jlb1 = new JLabel("请投币:"); jlb2 = new JLabel("请选择商品:"); jlb3 = new JLabel("请取饮料:"); jlb5 = new JLabel(""); jlb4 = new JLabel("找零:"); jlb6 = new JLabel(""); jrb1 = new JRadioButton("一元"); jrb2 = new JRadioButton("五角"); ButtonGroup bg1 = new ButtonGroup(); bg1.add(jrb1); bg1.add(jrb2); jrb3 = new JRadioButton("啤酒"); jrb4 = new JRadioButton("橙汁"); ButtonGroup bg2 = new ButtonGroup(); bg2.add(jrb3); bg2.add(jrb4); jb1 = new JButton("确定"); jb2 = new JButton("复位"); this.setLayout(new GridLayout(4,1)); jp1.add(jlb1); jp1.add(jrb1); jp1.add(jrb2); jp2.add(jlb2); jp2.add(jrb3); jp2.add(jrb4); jp3.add(jb1); jp3.add(jb2); jp4.add(jlb3); jp4.add(jlb5); jp4.add(jlb4); jp4.add(jlb6); this.add(jp1); this.add(jp2); this.add(jp3); this.add(jp4); this.setSize(300,200); this.setTitle("自动售货机"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); jrb1.addActionListener(new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { money = 0; if(jrb1.isSelected()) money = 1; } }); jrb2.addActionListener(new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { money = 0; if(jrb2.isSelected()) money = 0.5; } }); jrb3.addActionListener(new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { info = ""; if(jrb3.isSelected()) info = "啤酒"; } }); jrb4.addActionListener(new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { info = ""; if(jrb4.isSelected()) info = "橙汁"; } }); jb1.addActionListener(new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { jlb5.setText(info); if(money == 0) { jlb5.setText(""); jlb6.setText("0"); } else { money -= 0.5; String fromDouble = "" + money; jlb6.setText(fromDouble); money = 0; } } }); jb2.addActionListener(new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { jrb1.setSelected(false); jrb2.setSelected(false); jrb3.setSelected(false); jrb4.setSelected(false); if(money != 0){ String fromDouble = "" + money; jlb6.setText(fromDouble); money = 0; info = ""; jlb5.setText(info); } else{ info = ""; jlb5.setText(info); String fromDouble = "" + money; jlb6.setText(fromDouble); } } }); } }
用因果图法测试该程序,并撰写实验报告。
实验步骤:
①编写程序
②分析原因与结果
③画出因果图
④转化为决策表
⑤根据决策表设计测试用例,得到测试用例表
②分析原因与结果
原因 |
结果 |
C1、A、B |
M1 |
C3、B、C6 |
M2 |
A、C4、C6 |
M3 |
A、C5、C6 |
M4 |
C1:点复位 C2:投五角 C3:投一元 C4:选啤酒 C5:选橙汁 C6:点确定
A:售货机收到五角 B:选择一款饮料
M1:退钱 M2:找五角 M3:选啤酒 M4:选橙汁
③
画出因果图
④ 转化为决策表
|
1 |
2 |
3 |
4 |
5 |
6 |
|
输入 |
1 |
Y |
N |
Y |
Y |
N |
N |
0.5 |
N |
Y |
N |
N |
Y |
Y |
|
啤酒 |
- |
- |
Y |
N |
Y |
N |
|
橙汁 |
- |
- |
N |
Y |
N |
Y |
|
复位 |
Y |
Y |
N |
N |
N |
N |
|
确定 |
N |
N |
Y |
Y |
Y |
Y |
|
输出 |
1 |
√ |
|
|
|
|
|
0.5 |
|
√ |
√ |
√ |
|
|
|
啤酒 |
|
|
√ |
|
√ |
|
|
橙汁 |
|
|
|
√ |
|
√ |
⑤ 根据决策表设计测试用例,得到测试用例表
编号 |
金额 |
饮料 |
按钮 |
输出 |
1 |
1 |
- |
复位 |
1 |
2 |
0.5 |
- |
复位 |
0.5 |
3 |
1 |
啤酒 |
确定 |
1,啤酒 |
4 |
1 |
橙汁 |
确定 |
0.5,橙汁 |
5 |
0.5 |
啤酒 |
确定 |
啤酒 |
6 |
0.5 |
橙汁 |
确定 |
橙汁 |
4、航空服务查询问题:根据航线,仓位,飞行时间查询航空服务。
假设一个中国的航空公司规定:
① 中国去欧美的航线所有座位都有食物供应,每个座位都可以播放电影。
② 中国去非欧美的国外航线都有食物供应,只有商务仓可以播放电影。
③ 中国国内的航班的商务仓有食物供应,但是不可以播放电影
④ 中国国内航班的经济仓只有当飞行时间大于2小时时才有食物供应,但是不可以播放电影。
请用程序实现上述功能,并用决策表法设计测试用例,再执行测试,撰写实验报告。
实验步骤:
① 编写程序
② 构造决策表
③ 根据决策表设计测试用例,得到测试用例表
① 因果图
② 构造决策表
|
1 |
2 |
3 |
4 |
5 |
6 |
|
条件桩 |
欧美 |
Y |
N |
N |
N |
N |
N |
国外非欧美 |
N |
Y |
Y |
N |
N |
N |
|
国内 |
N |
N |
N |
Y |
Y |
Y |
|
商务舱 |
- |
Y |
N |
Y |
N |
N |
|
经济舱 |
- |
N |
Y |
N |
Y |
Y |
|
两小时以内 |
- |
- |
- |
- |
Y |
N |
|
超过两小时 |
- |
- |
- |
- |
N |
Y |
|
动作桩 |
食物供应 |
√ |
√ |
√ |
√ |
|
√ |
播放电影 |
√ |
√ |
|
|
|
|
③ 根据决策表设计测试用例,得到测试用例表
编号 |
航线 |
舱位 |
时间 |
输出 |
1 |
欧美 |
经济舱 |
两小时以内 |
食物+电影 |
2 |
国外非欧美 |
商务舱 |
两小时以内 |
食物+电影 |
3 |
国外非欧美 |
经济舱 |
两小时以内 |
食物 |
4 |
国内 |
商务舱 |
两小时以内 |
食物 |
5 |
国内 |
经济舱 |
超过两小时 |
食物 |
6 |
国内 |
经济舱 |
两小时以内 |
无任何服务 |
四、实验思考
1.先要对需求做充足的分析,结合被测对象的特点,列出等价类。
2.在此基础上分析出所有边界值,包括隐性的边界。
3.在上述两类集合中选取交集,进行用例设计。
尊崇以下原则:
•根据输入参数的代表值组合而成的有效等价类和无效测试用例按照测试用例的使用频率和重要程度排序,为每个测试用例设置不同的优先级,根据时间和资源的实际情况,有针对性地选择要执行的测试用例;
•优先选择包含边界值和边界值组合的测试用例;
•将一个等价类的每个代表值和其他等价类的每个代表值组合设计测试用例;
•保证满足最小原则,及一个等价类的每个代表值至少在一个测试用例中出现。
以上是黑盒测试减少测试用例的方法和原则。