5.8
软件测试02(源代码)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
def get_weekday(year, month, day): """ 输入年、月、日,返回星期几(中文字符串) """ # 分支1:检查月份范围 if month < 1 or month > 12: raise ValueError("月份必须在1到12之间") # 分支2:检查日期范围(基本范围1~31) if day < 1 or day > 31: raise ValueError("日期必须在1到31之间") # 分支3:对30天月份的检查 if month in [4, 6, 9, 11] and day > 30: raise ValueError(f"{month}月最多只有30天") # 分支4:对2月的检查(闰年与非闰年) if month == 2: is_leap = (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0) if is_leap: if day > 29: raise ValueError("闰年2月最多29天") else: if day > 28: raise ValueError("非闰年2月最多28天") # 分支5:当月份为1或2时,需要调整为上一年的 13、14 月 if month < 3: month += 12 year -= 1 # 分支6:计算 Zeller 公式 k = year % 100 # 年内年份 j = year // 100 # 世纪数 h = (day + (13 * (month + 1)) // 5 + k + k // 4 + j // 4 + 5 * j) % 7 # 分支7:将 Zeller 公式的结果映射为中文星期 weekday_map = { 0: "星期六", 1: "星期日", 2: "星期一", 3: "星期二", 4: "星期三", 5: "星期四", 6: "星期五" } return weekday_map[h]def run_test_cases(): """ 自动化测试用例,测试用例表格如下: | 用例编号 | 输入数据 (year, month, day) | 预期结果 | 覆盖逻辑分支说明 | |----------|-----------------------------|-------------------------------------------|-----------------------------------------------------| | 1 | (2023, 0, 10) | 抛出异常:“月份必须在1到12之间” | 分支1:month < 1 | | 2 | (2023, 13, 10) | 抛出异常:“月份必须在1到12之间” | 分支1:month > 12 | | 3 | (2023, 5, 0) | 抛出异常:“日期必须在1到31之间” | 分支2:day < 1 | | 4 | (2023, 5, 32) | 抛出异常:“日期必须在1到31之间” | 分支2:day > 31 | | 5 | (2023, 4, 31) | 抛出异常:“4月最多只有30天” | 分支3:针对4月(30天)的日期检查 | | 6 | (2023, 2, 29) | 抛出异常:“非闰年2月最多28天” | 分支4:非闰年2月日期检查 | | 7 | (2023, 2, 28) | 正确返回对应星期几(根据 Zeller 算法计算结果) | 分支4:非闰年2月有效日期 | | 8 | (2024, 2, 29) | 正确返回对应星期几(根据 Zeller 算法计算结果) | 分支4:闰年2月有效日期 | | 9 | (2023, 1, 15) | 正确返回对应星期几(根据 Zeller 算法计算结果) | 分支5:月份为1,调整为上一年的 13 月,年份减1 | | 10 | (2023, 3, 10) | 正确返回对应星期几(根据 Zeller 算法计算结果) | 正常日期,无需进入月份调整分支 | """ test_cases = [ (1, (2023, 0, 10), "异常: 月份必须在1到12之间"), (2, (2023, 13, 10), "异常: 月份必须在1到12之间"), (3, (2023, 5, 0), "异常: 日期必须在1到31之间"), (4, (2023, 5, 32), "异常: 日期必须在1到31之间"), (5, (2023, 4, 31), "异常: 4月最多只有30天"), (6, (2023, 2, 29), "异常: 非闰年2月最多28天"), (7, (2023, 2, 28), "正确"), (8, (2024, 2, 29), "正确"), (9, (2023, 1, 15), "正确"), (10, (2023, 3, 10), "正确"), ] print("===== 自动化测试开始 =====") for case_id, (year, month, day), expected in test_cases: try: result = get_weekday(year, month, day) if expected.startswith("正确"): print(f"用例{case_id}通过,输入({year}, {month}, {day}) -> 输出:{result}") else: print(f"用例{case_id}失败:预期异常,但函数返回了:{result}") except ValueError as ve: if expected.startswith("异常") and expected.split(":")[1].strip() in str(ve): print(f"用例{case_id}通过,输入({year}, {month}, {day}) -> 抛出异常:{ve}") else: print(f"用例{case_id}失败,输入({year}, {month}, {day}) -> 异常信息:{ve}") print("===== 自动化测试结束 =====\n")def interactive_mode(): """ 交互模式:用户可以不断输入日期进行测试,输入 q 退出。 """ print("进入交互模式,请按提示输入日期(格式:年 月 日),输入 q 退出:") while True: inp = input("请输入(例如 2023 12 25):") if inp.lower() == "q": print("退出交互模式。") break try: parts = inp.split() if len(parts) != 3: print("输入格式错误,请输入 年 月 日 三个数字。") continue year, month, day = map(int, parts) result = get_weekday(year, month, day) print(f"日期 {year}-{month}-{day} 对应的星期为:{result}") except ValueError as e: print(f"输入错误:{e}") except Exception as ex: print(f"发生错误:{ex}")if __name__ == "__main__": # 先运行自动化测试用例 run_test_cases() # 测试结束后进入交互模式 interactive_mode() |
02
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
import tkinter as tkfrom tkinter import messageboxdef get_change_str(R, P): """ 根据商品价格 R 与付款金额 P 计算找零最佳组合,返回结果字符串。 若无需找零则返回 "无需找零"。 输入验证:R 和 P 必须在 0~100 范围内,且 P >= R,否则抛出 ValueError 异常。 """ # 输入验证 if R < 0 or R > 100: raise ValueError("价格必须为0-100的整数") if P < 0 or P > 100: raise ValueError("付款金额必须为0-100的整数") if P < R: raise ValueError("付款金额不足") # 计算找零金额 change = P - R if change == 0: return "无需找零" # 分解货币组合 N50 = change // 50 remaining = change % 50 N10 = remaining // 10 remaining %= 10 N5 = remaining // 5 remaining %= 5 N1 = remaining # 构建结果字符串 result = [] if N50 > 0: result.append(f"50元: {N50}张") if N10 > 0: result.append(f"10元: {N10}张") if N5 > 0: result.append(f"5元: {N5}张") if N1 > 0: result.append(f"1元: {N1}张") total = N50 + N10 + N5 + N1 result.append(f"\n总张数: {total}") return "\n".join(result)def calculate_change(): """ 从界面获取输入,调用 get_change_str() 进行计算, 并将结果显示在文本框中。 """ result_text.delete(1.0, tk.END) try: R = int(entry_R.get()) P = int(entry_P.get()) result = get_change_str(R, P) result_text.insert(tk.END, result) except ValueError as e: messagebox.showerror("错误", str(e))def run_test_cases(): """ 运行基本路径法设计的测试用例,共6个场景, 在结果显示区依次输出每个测试用例的输入、预期输出和实际输出。 """ test_cases = [ # 用例编号, 商品价格 R, 付款金额 P, 预期输出描述 (1, 100, 100, "无需找零"), (2, 98, 100, "1元: 2张\n\n总张数: 2"), (3, 95, 100, "5元: 1张\n\n总张数: 1"), (4, 87, 100, "10元: 1张\n1元: 3张\n\n总张数: 4"), (5, 45, 100, "50元: 1张\n5元: 1张\n\n总张数: 2"), (6, 1, 100, "50元: 1张\n10元: 4张\n5元: 1张\n1元: 4张\n\n总张数: 10"), ] result_text.delete(1.0, tk.END) result_text.insert(tk.END, "===== 测试用例运行结果 =====\n") for case in test_cases: case_id, R, P, expected = case try: actual = get_change_str(R, P) result_text.insert(tk.END, f"\n用例{case_id}:\n") result_text.insert(tk.END, f" 输入: 价格={R}, 付款={P}\n") result_text.insert(tk.END, f" 预期输出:\n{expected}\n") result_text.insert(tk.END, f" 实际输出:\n{actual}\n") if actual == expected: result_text.insert(tk.END, " 结果: 通过\n") else: result_text.insert(tk.END, " 结果: 失败\n") except Exception as e: result_text.insert(tk.END, f"\n用例{case_id}异常: {e}\n") result_text.insert(tk.END, "\n===== 测试结束 =====\n")def create_gui(): """ 创建图形界面,包含输入区、按钮区和结果显示区。 """ global root, entry_R, entry_P, result_text root = tk.Tk() root.title("找零钱最佳组合计算器") root.geometry("450x400") # 输入区域 frame_input = tk.Frame(root) frame_input.pack(pady=10) tk.Label(frame_input, text="商品价格 (0-100元):").grid(row=0, column=0, padx=5, sticky=tk.E) entry_R = tk.Entry(frame_input, width=10) entry_R.grid(row=0, column=1, padx=5) tk.Label(frame_input, text="付款金额 (0-100元):").grid(row=1, column=0, padx=5, sticky=tk.E) entry_P = tk.Entry(frame_input, width=10) entry_P.grid(row=1, column=1, padx=5) # 按钮区域 frame_buttons = tk.Frame(root) frame_buttons.pack(pady=5) btn_calculate = tk.Button(frame_buttons, text="计算找零", command=calculate_change) btn_calculate.grid(row=0, column=0, padx=10) btn_test = tk.Button(frame_buttons, text="运行测试用例", command=run_test_cases) btn_test.grid(row=0, column=1, padx=10) # 结果展示区域 result_text = tk.Text(root, height=15, width=50) result_text.pack(pady=10) root.mainloop()if __name__ == "__main__": create_gui() |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
import tkinter as tkfrom tkinter import ttk, messageboxclass VendingMachine: @staticmethod def vend(coin, button): """自动售货机核心逻辑""" if coin not in [0.5, 1.0] or button not in ["橙汁", "啤酒"]: return "无效输入:金额或按钮不合法" if coin == 0.5: return f"送出{button}", "无找零" elif coin == 1.0: return f"送出{button}", "退回5角硬币"class ClassicVendingGUI: def __init__(self, root): self.root = root self.root.title("自动售货机模拟程序") self.root.geometry("400x350") # 初始化变量 self.coin = tk.DoubleVar(value=0.0) self.drink = tk.StringVar() # 创建界面 self.create_widgets() # 配置样式 self.configure_style() def configure_style(self): """配置经典样式""" style = ttk.Style() style.configure("TRadiobutton", font=("微软雅黑", 10)) style.configure("TButton", font=("微软雅黑", 10), width=8) style.configure("TLabel", font=("微软雅黑", 10)) def create_widgets(self): """创建经典界面组件""" main_frame = ttk.Frame(self.root) main_frame.pack(padx=20, pady=10, fill=tk.BOTH, expand=True) # 投币区域 coin_frame = ttk.LabelFrame(main_frame, text="请拨币") coin_frame.pack(fill=tk.X, pady=5) ttk.Radiobutton(coin_frame, text="无", variable=self.coin, value=0.0).pack(side=tk.LEFT, padx=5) ttk.Radiobutton(coin_frame, text="五角", variable=self.coin, value=0.5).pack(side=tk.LEFT, padx=5) ttk.Radiobutton(coin_frame, text="一元", variable=self.coin, value=1.0).pack(side=tk.LEFT, padx=5) # 商品选择区域 product_frame = ttk.LabelFrame(main_frame, text="请选择商品") product_frame.pack(fill=tk.X, pady=5) ttk.Button(product_frame, text="啤酒", command=lambda: self.drink.set("啤酒")).pack(side=tk.LEFT, padx=10, pady=5) ttk.Button(product_frame, text="橙汁", command=lambda: self.drink.set("橙汁")).pack(side=tk.LEFT, padx=10, pady=5) # 操作按钮区域 btn_frame = ttk.Frame(main_frame) btn_frame.pack(pady=10) ttk.Button(btn_frame, text="确定", command=self.process).pack(side=tk.LEFT, padx=5) ttk.Button(btn_frame, text="复位", command=self.reset).pack(side=tk.LEFT, padx=5) ttk.Button(btn_frame, text="运行测试用例", command=self.run_tests).pack(side=tk.LEFT, padx=5) # 输出区域 output_frame = ttk.LabelFrame(main_frame, text="输出") output_frame.pack(fill=tk.X, pady=5) ttk.Label(output_frame, text="请取饮料:").pack(side=tk.LEFT, padx=5) self.drink_label = ttk.Label(output_frame, text="", foreground="blue") self.drink_label.pack(side=tk.LEFT, padx=5) ttk.Label(output_frame, text="找零:").pack(side=tk.LEFT, padx=5) self.change_label = ttk.Label(output_frame, text="", foreground="green") self.change_label.pack(side=tk.LEFT, padx=5) def process(self): """处理购买请求""" coin = self.coin.get() drink = self.drink.get() # 输入验证 if coin == 0.0: messagebox.showerror("错误", "请先投币!") return if not drink: messagebox.showerror("错误", "请选择饮料!") return # 获取结果 result = VendingMachine.vend(coin, drink) # 显示结果 if isinstance(result, tuple): self.drink_label.config(text=result[0]) self.change_label.config(text=result[1]) else: messagebox.showerror("错误", result) def reset(self): """复位所有选项""" self.coin.set(0.0) self.drink.set("") self.drink_label.config(text="") self.change_label.config(text="") def run_tests(self): """运行自动测试用例,并在新窗口显示结果""" # 定义测试用例:(投币, 商品, 预期输出) test_cases = [ (0.5, "橙汁", ("送出橙汁", "无找零")), (0.5, "啤酒", ("送出啤酒", "无找零")), (1.0, "橙汁", ("送出橙汁", "退回5角硬币")), (1.0, "啤酒", ("送出啤酒", "退回5角硬币")), ] results = [] for idx, (coin, drink, expected) in enumerate(test_cases, start=1): actual = VendingMachine.vend(coin, drink) result_str = f"用例{idx}: 投币={coin}, 商品={drink}\n" result_str += f" 预期: {expected}\n" result_str += f" 实际: {actual}\n" if actual == expected: result_str += " 结果: 通过\n" else: result_str += " 结果: 失败\n" results.append(result_str) # 新建测试结果窗口 test_win = tk.Toplevel(self.root) test_win.title("测试结果") test_text = tk.Text(test_win, width=60, height=15) test_text.pack(padx=10, pady=10) test_text.insert(tk.END, "\n".join(results)) test_text.config(state=tk.DISABLED)if __name__ == "__main__": root = tk.Tk() app = ClassicVendingGUI(root) root.mainloop() |
import tkinter as tk
from tkinter import messagebox, ttk
def query_service():
route = route_var.get()
seat = seat_var.get()
flight_time = flight_time_var.get()
food_service = "无"
movie_service = "无"
if route == "欧美":
food_service = "有"
movie_service = "有"
elif route == "国外非欧美":
food_service = "有"
movie_service = "有" if seat == "商务舱" else "无"
elif route == "国内":
if seat == "商务舱":
food_service = "有"
elif seat == "经济舱" and flight_time == "超过两小时":
food_service = "有"
result_var.set(f"食物供应: {food_service}, 电影播放: {movie_service}")
def run_all_tests():
test_cases = [
("欧美", "商务舱", "两小时以内"),
("欧美", "经济舱", "超过两小时"),
("国外非欧美", "商务舱", "两小时以内"),
("国外非欧美", "经济舱", "超过两小时"),
("国内", "商务舱", "两小时以内"),
("国内", "商务舱", "超过两小时"),
("国内", "经济舱", "两小时以内"),
("国内", "经济舱", "超过两小时"),
]
results = []
for route, seat, flight_time in test_cases:
route_var.set(route)
seat_var.set(seat)
flight_time_var.set(flight_time)
query_service()
results.append(f"航线: {route}, 舱位: {seat}, 飞行时间: {flight_time} -> {result_var.get()}")
messagebox.showinfo("测试用例结果", "\n".join(results))
root = tk.Tk()
root.title("航空服务查询")
route_var = tk.StringVar()
seat_var = tk.StringVar()
flight_time_var = tk.StringVar()
result_var = tk.StringVar()
frame = ttk.LabelFrame(root, text="航线")
frame.pack(pady=5)
ttk.Radiobutton(frame, text="欧美", variable=route_var, value="欧美").pack(side=tk.LEFT)
ttk.Radiobutton(frame, text="国外非欧美", variable=route_var, value="国外非欧美").pack(side=tk.LEFT)
ttk.Radiobutton(frame, text="国内", variable=route_var, value="国内").pack(side=tk.LEFT)
frame = ttk.LabelFrame(root, text="舱位")
frame.pack(pady=5)
ttk.Radiobutton(frame, text="商务舱", variable=seat_var, value="商务舱").pack(side=tk.LEFT)
ttk.Radiobutton(frame, text="经济舱", variable=seat_var, value="经济舱").pack(side=tk.LEFT)
frame = ttk.LabelFrame(root, text="飞行时间")
frame.pack(pady=5)
ttk.Radiobutton(frame, text="两小时以内", variable=flight_time_var, value="两小时以内").pack(side=tk.LEFT)
ttk.Radiobutton(frame, text="超过两小时", variable=flight_time_var, value="超过两小时").pack(side=tk.LEFT)
ttk.Button(root, text="查询", command=query_service).pack(pady=5)
ttk.Label(root, textvariable=result_var).pack(pady=5)
ttk.Button(root, text="运行所有测试用例", command=run_all_tests).pack(pady=5)
ttk.Button(root, text="退出", command=root.quit).pack(pady=5)
root.mainloop()
class SalaryManager:
def __init__(self, emp_tab, dept_tab):
self.emp_tab = emp_tab # 格式: [{"name": str, "job": str, "dept": str, "salary": float}, ...]
self.dept_tab = dept_tab # 格式: [{"dept": str, "sales": int}, ...]
self.ERRCODE = 0
def process_salary(self):
esize = len(self.emp_tab)
dsize = len(self.dept_tab)
# 错误码1: 输入表为空
if esize <= 0 or dsize <= 0:
self.ERRCODE = 1
return self.ERRCODE
# 找到最大销售量
max_sales = max(dept["sales"] for dept in self.dept_tab)
# 遍历所有部门,处理最大销售量的部门
found_any_employee = False
for dept in self.dept_tab:
if dept["sales"] == max_sales:
dept_name = dept["dept"]
found_in_dept = False
# 处理该部门的员工
for emp in self.emp_tab:
if emp["dept"] == dept_name:
found_in_dept = True
found_any_employee = True
if emp["salary"] >= 15000.00 or emp["job"] == "M":
emp["salary"] += 100.00
else:
emp["salary"] += 200.00
# 如果当前部门无员工,可能触发错误码2
if not found_in_dept:
self.ERRCODE = 2
# 如果存在至少一个部门有员工,覆盖错误码为0
if found_any_employee:
self.ERRCODE = 0
return self.ERRCODE
# 测试用例
if __name__ == "__main__":
# 测试用例1: 输入表为空 → ERRCODE=1
emp_empty = []
dept_empty = []
manager = SalaryManager(emp_empty, [{"dept": "A", "sales": 100}])
assert manager.process_salary() == 1
# 测试用例2: 最大销售量部门无员工 → ERRCODE=2
emp_tab = [{"name": "Bob", "job": "E", "dept": "B", "salary": 12000}]
dept_tab = [{"dept": "A", "sales": 200}, {"dept": "B", "sales": 150}]
manager = SalaryManager(emp_tab, dept_tab)
assert manager.process_salary() == 2
# 测试用例3: 工资≥15000 → 加100元
emp_tab = [{"name": "Charlie", "job": "E", "dept": "A", "salary": 16000}]
dept_tab = [{"dept": "A", "sales": 200}]
manager = SalaryManager(emp_tab, dept_tab)
manager.process_salary()
assert emp_tab[0]["salary"] == 16100.00
# 测试用例4: 职务=经理 → 加100元
emp_tab = [{"name": "David", "job": "M", "dept": "A", "salary": 14000}]
manager = SalaryManager(emp_tab, dept_tab)
manager.process_salary()
assert emp_tab[0]["salary"] == 14100.00
# 测试用例5: 正常员工 → 加200元
emp_tab = [{"name": "Eve", "job": "E", "dept": "A", "salary": 14000}]
manager = SalaryManager(emp_tab, dept_tab)
manager.process_salary()
assert emp_tab[0]["salary"] == 14200.00
# 测试用例6: 多部门并列最大销售量 → 所有部门员工调整
emp_tab = [
{"name": "Frank", "job": "E", "dept": "A", "salary": 12000},
{"name": "Grace", "job": "E", "dept": "B", "salary": 13000}
]
dept_tab = [
{"dept": "A", "sales": 300},
{"dept": "B", "sales": 300}
]
manager = SalaryManager(emp_tab, dept_tab)
manager.process_salary()
assert emp_tab[0]["salary"] == 12200.00
assert emp_tab[1]["salary"] == 13200.00
print("所有测试用例通过!")

浙公网安备 33010602011771号