假设一个中国的航空公司规定:
① 中国去欧美的航线所有座位都有食物供应,每个座位都可以播放电影。
② 中国去非欧美的国外航线都有食物供应,只有商务仓可以播放电影。
③ 中国国内的航班的商务仓有食物供应,但是不可以播放电影
④ 中国国内航班的经济仓只有当飞行时间大于2小时时才有食物供应,但是不可以播放电影。
请用程序实现上述功能,并用决策表法设计测试用例,再执行测试,撰写实验报告。
实验步骤:
① 编写程序
package org.example;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class AirlineService {
private static String food = "无食物供应";
private static String movie = "无电影播放";
public static void main(String[] args) {
JFrame frame = new JFrame("航空服务选择");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setLayout(new GridLayout(7, 2));
// 创建航线选择按钮组
JPanel routePanel = new JPanel();
routePanel.setLayout(new GridLayout(1, 3));
routePanel.add(new JLabel("请选择航线:"));
JRadioButton route1 = new JRadioButton("1. 欧美");
JRadioButton route2 = new JRadioButton("2. 国外非欧美");
JRadioButton route3 = new JRadioButton("3. 国内");
ButtonGroup routeGroup = new ButtonGroup();
routeGroup.add(route1);
routeGroup.add(route2);
routeGroup.add(route3);
routePanel.add(route1);
routePanel.add(route2);
routePanel.add(route3);
// 创建舱位选择按钮组
JPanel seatPanel = new JPanel();
seatPanel.setLayout(new GridLayout(1, 2));
seatPanel.add(new JLabel("请选择舱位:"));
JRadioButton seat1 = new JRadioButton("1. 商务舱");
JRadioButton seat2 = new JRadioButton("2. 经济舱");
ButtonGroup seatGroup = new ButtonGroup();
seatGroup.add(seat1);
seatGroup.add(seat2);
seatPanel.add(seat1);
seatPanel.add(seat2);
// 创建飞行时间选择按钮组
JPanel timePanel = new JPanel();
timePanel.setLayout(new GridLayout(1, 2));
timePanel.add(new JLabel("请选择飞行时间:"));
JRadioButton time1 = new JRadioButton("1. 两小时以内");
JRadioButton time2 = new JRadioButton("2. 超过两小时");
ButtonGroup timeGroup = new ButtonGroup();
timeGroup.add(time1);
timeGroup.add(time2);
timePanel.add(time1);
timePanel.add(time2);
JButton submitButton = new JButton("提交");
JButton resetButton = new JButton("重置");
JLabel foodLabel = new JLabel("食物供应:");
JLabel movieLabel = new JLabel("电影播放:");
frame.add(routePanel);
frame.add(seatPanel);
frame.add(timePanel);
frame.add(submitButton);
frame.add(resetButton);
frame.add(foodLabel);
frame.add(movieLabel);
submitButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int route = getSelectedButtonIndex(route1, route2, route3) + 1;
int seat = getSelectedButtonIndex(seat1, seat2) + 1;
int time = getSelectedButtonIndex(time1, time2) + 1;
food = "无食物供应";
movie = "无电影播放";
if (route == 1) { // 欧美航线
food = "有食物供应";
movie = "可以播放电影";
} else if (route == 2) { // 国外非欧美航线
food = "有食物供应";
if (seat == 1) { // 商务舱
movie = "可以播放电影";
}
} else if (route == 3) { // 国内航线
if (seat == 1) { // 商务舱
food = "有食物供应";
} else if (seat == 2 && time == 2) { // 经济舱且飞行时间超过两小时
food = "有食物供应";
}
}
foodLabel.setText("食物供应:" + food);
movieLabel.setText("电影播放:" + movie);
}
});
resetButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
food = "无食物供应";
movie = "无电影播放";
foodLabel.setText("食物供应:" + food);
movieLabel.setText("电影播放:" + movie);
}
});
frame.setVisible(true);
}
private static int getSelectedButtonIndex(JRadioButton... buttons) {
for (JRadioButton button : buttons) {
if (button.isSelected()) {
return buttons.indexOf(button);
}
}
return -1;
}
}
② 构造决策表
序号 |
航线 |
舱位 |
飞行时间 |
食物供应 |
电影播放 |
1 |
欧美 |
商务舱 |
两小时以内 |
有 |
可以 |
2 |
欧美 |
商务舱 |
超过两小时 |
有 |
可以 |
3 |
欧美 |
经济舱 |
两小时以内 |
有 |
可以 |
4 |
欧美 |
经济舱 |
超过两小时 |
有 |
可以 |
5 |
国外非欧美 |
商务舱 |
两小时以内 |
有 |
可以 |
6 |
国外非欧美 |
商务舱 |
超过两小时 |
有 |
可以 |
7 |
国外非欧美 |
经济舱 |
两小时以内 |
有 |
无 |
8 |
国外非欧美 |
经济舱 |
超过两小时 |
有 |
无 |
9 |
国内 |
商务舱 |
两小时以内 |
有 |
无 |
10 |
国内 |
商务舱 |
超过两小时 |
有 |
无 |
11 |
国内 |
经济舱 |
两小时以内 |
无 |
无 |
12 |
国内 |
经济舱 |
超过两小时 |
有 |
无 |
③ 根据决策表设计测试用例,得到测试用例表
序号 |
输入数据 |
预期输出 |
1 |
航线:欧美,舱位:商务舱,飞行时间:两小时以内 |
食物供应:有,电影播放:可以 |
2 |
航线:欧美,舱位:商务舱,飞行时间:超过两小时 |
食物供应:有,电影播放:可以 |
3 |
航线:欧美,舱位:经济舱,飞行时间:两小时以内 |
食物供应:有,电影播放:可以 |
4 |
航线:欧美,舱位:经济舱,飞行时间:超过两小时 |
食物供应:有,电影播放:可以 |
5 |
航线:国外非欧美,舱位:商务舱,飞行时间:两小时以内 |
食物供应:有,电影播放:可以 |
6 |
航线:国外非欧美,舱位:商务舱,飞行时间:超过两小时 |
食物供应:有,电影播放:可以 |
7 |
航线:国外非欧美,舱位:经济舱,飞行时间:两小时以内 |
食物供应:有,电影播放:无 |
8 |
航线:国外非欧美,舱位:经济舱,飞行时间:超过两小时 |
食物供应:有,电影播放:无 |
9 |
航线:国内,舱位:商务舱,飞行时间:两小时以内 |
食物供应:有,电影播放:无 |
10 |
航线:国内,舱位:商务舱,飞行时间:超过两小时 |
食物供应:有,电影播放:无 |
11 |
航线:国内,舱位:经济舱,飞行时间:两小时以内 |
食物供应:无,电影播放:无 |
12 |
航线:国内,舱位:经济舱,飞行时间:超过两小时 |
食物供应:有,电影播放:无 |
四、实验思考
① 在实际的测试中,如何设计测试用例才能达到用最少的测试用例检测出最多的缺陷;
理解需求:
彻底理解软件的需求和功能,确保测试用例覆盖所有功能点。
等价类划分:
使用等价类划分方法,将输入数据划分为有效和无效等价类,确保每个等价类至少有一个测试用例。
边界值分析:
专注于输入的边界条件,这些通常是缺陷的高发区域。
因果图法:
使用因果图法来识别输入条件和输出结果之间的因果关系,确保所有可能的输入组合都被测试。
决策表法:
当存在多个条件影响一个输出时,使用决策表法来设计测试用例,确保所有条件的组合都被覆盖。
错误猜测:
基于经验和直觉,猜测可能出错的地方,并为这些区域编写测试用例。
回归测试:
在软件修改后,对之前发现缺陷的区域进行回归测试,确保修改没有引入新的问题。
自动化测试:
尽可能自动化测试用例,以提高测试的效率和重复执行的准确性。
风险驱动测试:
根据软件的功能和业务影响,识别高风险区域并优先测试。
持续集成:
在软件开发过程中持续集成测试,确保新代码不会破坏现有功能。
② 在进行用例设计时,如何考虑软件测试用例的充分性和减少软件测试用例的冗余性;
需求分析:
详细分析软件需求,确保测试用例覆盖所有需求。
避免重复:
检查测试用例集,避免重复测试相同的功能或逻辑。
最小化冗余:
使用等价类划分和边界值分析来最小化测试用例数量,同时保持充分性。
优先级排序:
根据测试用例的重要性和风险等级进行排序,优先测试关键功能。
分层测试:
结合单元测试、集成测试、系统测试和验收测试,确保每个层次都有足够的测试覆盖。
使用测试工具:
利用自动化测试工具来帮助识别和消除冗余的测试用例。
定期评审:
定期评审测试用例,移除不再需要的测试用例,添加新的测试用例以覆盖新的需求。
测试覆盖率分析:
使用代码覆盖率工具来分析测试用例的覆盖情况,确保关键代码被充分测试。
风险评估:
根据软件的风险评估结果,调整测试用例的设计,确保高风险区域得到充分测试。
持续优化:
根据测试结果和反馈,持续优化测试用例,提高测试效率和效果。