285 lines
9.9 KiB
Python
285 lines
9.9 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
学院专业班级联动功能测试脚本
|
|
验证修复后的前后端联动是否正常工作
|
|
|
|
日期: 2025-01-15
|
|
修复内容: 修复前后端数据结构不匹配,实现正确的三级联动
|
|
"""
|
|
|
|
import requests
|
|
import json
|
|
import sys
|
|
from datetime import datetime
|
|
|
|
# 配置信息
|
|
BASE_URL = "http://localhost:8080"
|
|
LOGIN_URL = f"{BASE_URL}/auth/login"
|
|
COLLEGE_OPTIONS_URL = f"{BASE_URL}/xg/studentInfo/options/colleges"
|
|
MAJOR_OPTIONS_URL = f"{BASE_URL}/xg/studentInfo/options/majors"
|
|
CLASS_OPTIONS_URL = f"{BASE_URL}/xg/studentInfo/options/classes"
|
|
|
|
# 登录配置
|
|
LOGIN_DATA = {
|
|
"username": "admin",
|
|
"password": "admin123",
|
|
"clientId": "e5cd7e4891bf95d1d19206ce24a7b32e",
|
|
"grantType": "password"
|
|
}
|
|
|
|
# 请求头配置
|
|
HEADERS = {
|
|
"Content-Type": "application/json",
|
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
|
|
"referer": "http://localhost",
|
|
"clientid": "e5cd7e4891bf95d1d19206ce24a7b32e"
|
|
}
|
|
|
|
def print_test_header(title):
|
|
"""打印测试标题"""
|
|
print(f"\n{'='*60}")
|
|
print(f"🧪 {title}")
|
|
print(f"{'='*60}")
|
|
|
|
def print_result(success, message, details=None):
|
|
"""打印测试结果"""
|
|
status = "✅ 成功" if success else "❌ 失败"
|
|
print(f"{status}: {message}")
|
|
if details:
|
|
print(f"详情: {details}")
|
|
|
|
def login():
|
|
"""登录获取token"""
|
|
print_test_header("步骤1: 用户登录")
|
|
|
|
try:
|
|
response = requests.post(LOGIN_URL, json=LOGIN_DATA, headers=HEADERS, timeout=10)
|
|
print(f"登录请求状态码: {response.status_code}")
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
if data.get("code") == 200:
|
|
token = data.get("data", {}).get("access_token")
|
|
if token:
|
|
print_result(True, "登录成功", f"Token: {token[:20]}...")
|
|
return token
|
|
else:
|
|
print_result(False, "登录响应中没有token", data)
|
|
else:
|
|
print_result(False, "登录失败", data.get("msg", "未知错误"))
|
|
else:
|
|
print_result(False, f"登录请求失败", f"状态码: {response.status_code}")
|
|
|
|
except Exception as e:
|
|
print_result(False, "登录异常", str(e))
|
|
|
|
return None
|
|
|
|
def test_college_options(token):
|
|
"""测试学院选项接口"""
|
|
print_test_header("步骤2: 测试学院选项接口")
|
|
|
|
test_headers = HEADERS.copy()
|
|
test_headers["Authorization"] = f"Bearer {token}"
|
|
|
|
try:
|
|
response = requests.get(COLLEGE_OPTIONS_URL, headers=test_headers, timeout=10)
|
|
print(f"学院选项请求状态码: {response.status_code}")
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
if data.get("code") == 200:
|
|
colleges = data.get("data", [])
|
|
print_result(True, f"获取学院选项成功", f"共 {len(colleges)} 个学院")
|
|
|
|
# 显示前3个学院信息
|
|
for i, college in enumerate(colleges[:3]):
|
|
print(f" 学院{i+1}: {college.get('label')} (代码: {college.get('value')})")
|
|
|
|
return colleges
|
|
else:
|
|
print_result(False, "获取学院选项失败", data.get("msg", "未知错误"))
|
|
else:
|
|
print_result(False, f"学院选项请求失败", f"状态码: {response.status_code}")
|
|
|
|
except Exception as e:
|
|
print_result(False, "学院选项请求异常", str(e))
|
|
|
|
return []
|
|
|
|
def test_major_options(token, college_code=None):
|
|
"""测试专业选项接口"""
|
|
test_name = f"测试专业选项接口 (学院代码: {college_code or '全部'})"
|
|
print_test_header(f"步骤3: {test_name}")
|
|
|
|
test_headers = HEADERS.copy()
|
|
test_headers["Authorization"] = f"Bearer {token}"
|
|
|
|
params = {}
|
|
if college_code:
|
|
params["collegeCode"] = college_code
|
|
|
|
try:
|
|
response = requests.get(MAJOR_OPTIONS_URL, headers=test_headers, params=params, timeout=10)
|
|
print(f"专业选项请求状态码: {response.status_code}")
|
|
print(f"请求参数: {params}")
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
if data.get("code") == 200:
|
|
majors = data.get("data", [])
|
|
print_result(True, f"获取专业选项成功", f"共 {len(majors)} 个专业")
|
|
|
|
# 显示前3个专业信息
|
|
for i, major in enumerate(majors[:3]):
|
|
print(f" 专业{i+1}: {major.get('label')} (代码: {major.get('value')})")
|
|
|
|
return majors
|
|
else:
|
|
print_result(False, "获取专业选项失败", data.get("msg", "未知错误"))
|
|
else:
|
|
print_result(False, f"专业选项请求失败", f"状态码: {response.status_code}")
|
|
|
|
except Exception as e:
|
|
print_result(False, "专业选项请求异常", str(e))
|
|
|
|
return []
|
|
|
|
def test_class_options(token, major_code=None):
|
|
"""测试班级选项接口"""
|
|
test_name = f"测试班级选项接口 (专业代码: {major_code or '全部'})"
|
|
print_test_header(f"步骤4: {test_name}")
|
|
|
|
test_headers = HEADERS.copy()
|
|
test_headers["Authorization"] = f"Bearer {token}"
|
|
|
|
params = {}
|
|
if major_code:
|
|
params["majorCode"] = major_code
|
|
|
|
try:
|
|
response = requests.get(CLASS_OPTIONS_URL, headers=test_headers, params=params, timeout=10)
|
|
print(f"班级选项请求状态码: {response.status_code}")
|
|
print(f"请求参数: {params}")
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
if data.get("code") == 200:
|
|
classes = data.get("data", [])
|
|
print_result(True, f"获取班级选项成功", f"共 {len(classes)} 个班级")
|
|
|
|
# 显示前3个班级信息
|
|
for i, class_item in enumerate(classes[:3]):
|
|
print(f" 班级{i+1}: {class_item.get('label')} (代码: {class_item.get('value')})")
|
|
|
|
return classes
|
|
else:
|
|
print_result(False, "获取班级选项失败", data.get("msg", "未知错误"))
|
|
else:
|
|
print_result(False, f"班级选项请求失败", f"状态码: {response.status_code}")
|
|
|
|
except Exception as e:
|
|
print_result(False, "班级选项请求异常", str(e))
|
|
|
|
return []
|
|
|
|
def test_cascade_logic(token):
|
|
"""测试完整的联动逻辑"""
|
|
print_test_header("步骤5: 测试完整的三级联动逻辑")
|
|
|
|
# 1. 获取学院列表
|
|
colleges = test_college_options(token)
|
|
if not colleges:
|
|
print_result(False, "无法获取学院列表,跳过联动测试")
|
|
return False
|
|
|
|
# 2. 选择第一个学院,获取其专业列表
|
|
first_college = colleges[0]
|
|
college_code = first_college.get("value")
|
|
college_name = first_college.get("label")
|
|
|
|
print(f"\n🎯 选择学院: {college_name} (代码: {college_code})")
|
|
majors = test_major_options(token, college_code)
|
|
|
|
if not majors:
|
|
print_result(False, f"学院 {college_name} 下没有专业,跳过班级测试")
|
|
return False
|
|
|
|
# 3. 选择第一个专业,获取其班级列表
|
|
first_major = majors[0]
|
|
major_code = first_major.get("value")
|
|
major_name = first_major.get("label")
|
|
|
|
print(f"\n🎯 选择专业: {major_name} (代码: {major_code})")
|
|
classes = test_class_options(token, major_code)
|
|
|
|
if not classes:
|
|
print_result(False, f"专业 {major_name} 下没有班级")
|
|
return False
|
|
|
|
# 4. 显示完整的联动结果
|
|
first_class = classes[0]
|
|
class_code = first_class.get("value")
|
|
class_name = first_class.get("label")
|
|
|
|
print(f"\n🎯 完整联动路径:")
|
|
print(f" 学院: {college_name} ({college_code})")
|
|
print(f" 专业: {major_name} ({major_code})")
|
|
print(f" 班级: {class_name} ({class_code})")
|
|
|
|
print_result(True, "三级联动测试成功", "学院→专业→班级联动正常")
|
|
return True
|
|
|
|
def main():
|
|
"""主函数"""
|
|
print("🔍 学院专业班级联动功能测试")
|
|
print(f"时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
|
print(f"目标: 验证修复后的三级联动功能")
|
|
|
|
# 1. 登录获取token
|
|
token = login()
|
|
if not token:
|
|
print("\n❌ 登录失败,无法继续测试")
|
|
sys.exit(1)
|
|
|
|
# 2. 测试各个选项接口
|
|
college_success = bool(test_college_options(token))
|
|
major_success = bool(test_major_options(token)) # 测试无条件的专业列表
|
|
class_success = bool(test_class_options(token)) # 测试无条件的班级列表
|
|
|
|
# 3. 测试完整联动逻辑
|
|
cascade_success = test_cascade_logic(token)
|
|
|
|
# 4. 总结测试结果
|
|
print_test_header("测试结果总结")
|
|
|
|
tests = [
|
|
("学院选项接口", college_success),
|
|
("专业选项接口", major_success),
|
|
("班级选项接口", class_success),
|
|
("三级联动逻辑", cascade_success)
|
|
]
|
|
|
|
passed = sum(1 for _, success in tests if success)
|
|
total = len(tests)
|
|
|
|
print(f"📊 测试统计: {passed}/{total} 通过")
|
|
|
|
for test_name, success in tests:
|
|
status = "✅" if success else "❌"
|
|
print(f"{status} {test_name}")
|
|
|
|
if passed == total:
|
|
print(f"\n🎉 所有测试通过!学院专业班级联动功能修复成功!")
|
|
print("✅ 前后端数据结构匹配正确")
|
|
print("✅ 三级联动逻辑工作正常")
|
|
print("✅ 专业和班级选项不再为空")
|
|
else:
|
|
print(f"\n⚠️ 部分测试失败,需要进一步排查问题")
|
|
|
|
return passed == total
|
|
|
|
if __name__ == "__main__":
|
|
success = main()
|
|
sys.exit(0 if success else 1) |