test:添加认证系统测试套件

- 添加UI测试场景,支持模拟各种认证场景
- 实现API测试脚本,覆盖登录、注册、验证码等接口
- 添加测试文档,说明测试用例和预期结果
- 支持自动化测试和手动测试验证
This commit is contained in:
2025-12-24 20:37:33 +08:00
parent c6bcca4e7f
commit 47cfc14f68
7 changed files with 1511 additions and 0 deletions

464
tests/auth/auth_ui_test.gd Normal file
View File

@@ -0,0 +1,464 @@
extends Control
# 认证UI测试场景
# 用于测试登录和注册界面的各种响应情况
@onready var auth_scene: Control = $AuthScene
@onready var test_panel: Panel = $TestPanel
@onready var test_buttons: VBoxContainer = $TestPanel/VBoxContainer/ScrollContainer/TestButtons
@onready var feedback_panel: Panel = $TestPanel/VBoxContainer/FeedbackPanel
@onready var feedback_text: RichTextLabel = $TestPanel/VBoxContainer/FeedbackPanel/FeedbackContainer/FeedbackScroll/FeedbackText
# 反馈样式 - 动态创建
var feedback_styles = {}
var test_scenarios = [
{
"name": "✅ 登录成功",
"type": "login",
"response_code": 200,
"response_data": {
"success": true,
"data": {
"user": {
"id": "123",
"username": "testuser",
"email": "test@example.com"
},
"token": "jwt_token_here"
},
"message": "登录成功"
}
},
{
"name": "❌ 登录失败-用户名或密码错误",
"type": "login",
"response_code": 401,
"response_data": {
"success": false,
"message": "用户名或密码错误",
"error_code": "INVALID_CREDENTIALS"
}
},
{
"name": "❌ 登录失败-用户不存在",
"type": "login",
"response_code": 404,
"response_data": {
"success": false,
"message": "用户不存在",
"error_code": "USER_NOT_FOUND"
}
},
{
"name": "❌ 登录失败-参数错误",
"type": "login",
"response_code": 400,
"response_data": {
"success": false,
"message": "用户名格式错误",
"error_code": "INVALID_PARAMETERS"
}
},
{
"name": "✅ 发送验证码成功",
"type": "send_code",
"response_code": 200,
"response_data": {
"success": true,
"data": {"verification_code": "123456"},
"message": "验证码已发送"
}
},
{
"name": "❌ 发送验证码-邮箱格式错误",
"type": "send_code",
"response_code": 400,
"response_data": {
"success": false,
"message": "邮箱格式错误",
"error_code": "INVALID_EMAIL"
}
},
{
"name": "❌ 发送验证码-请求过频",
"type": "send_code",
"response_code": 429,
"response_data": {
"success": false,
"message": "请求过于频繁",
"error_code": "TOO_MANY_REQUESTS"
}
},
{
"name": "❌ 发送验证码-服务器错误",
"type": "send_code",
"response_code": 500,
"response_data": {
"success": false,
"message": "服务器内部错误",
"error_code": "INTERNAL_ERROR"
}
},
{
"name": "❌ 发送验证码-网络错误",
"type": "send_code",
"response_code": 0,
"response_data": {}
},
{
"name": "✅ 邮箱验证成功",
"type": "verify_email",
"response_code": 200,
"response_data": {
"success": true,
"message": "邮箱验证成功"
}
},
{
"name": "❌ 邮箱验证-验证码错误",
"type": "verify_email",
"response_code": 400,
"response_data": {
"success": false,
"message": "验证码错误或已过期",
"error_code": "INVALID_CODE"
}
},
{
"name": "❌ 邮箱验证-验证码不存在",
"type": "verify_email",
"response_code": 404,
"response_data": {
"success": false,
"message": "验证码不存在",
"error_code": "CODE_NOT_FOUND"
}
},
{
"name": "✅ 注册成功",
"type": "register",
"response_code": 201,
"response_data": {
"success": true,
"data": {
"user": {
"id": "123",
"username": "testuser",
"email": "test@example.com"
}
},
"message": "注册成功"
}
},
{
"name": "❌ 注册失败-参数错误",
"type": "register",
"response_code": 400,
"response_data": {
"success": false,
"message": "用户名格式错误",
"error_code": "INVALID_USERNAME"
}
},
{
"name": "❌ 注册失败-缺少验证码",
"type": "register",
"response_code": 400,
"response_data": {
"success": false,
"message": "提供邮箱时必须提供邮箱验证码",
"error_code": "REGISTER_FAILED"
}
},
{
"name": "❌ 注册失败-用户已存在",
"type": "register",
"response_code": 409,
"response_data": {
"success": false,
"message": "用户名已存在",
"error_code": "USER_EXISTS"
}
},
{
"name": "❌ 注册失败-请求过频",
"type": "register",
"response_code": 429,
"response_data": {
"success": false,
"message": "注册请求过于频繁请5分钟后再试",
"error_code": "TOO_MANY_REQUESTS",
"throttle_info": {
"limit": 3,
"window_seconds": 300,
"current_requests": 3,
"reset_time": "2025-12-24T11:26:41.136Z"
}
}
},
{
"name": "❌ 注册失败-服务器错误",
"type": "register",
"response_code": 500,
"response_data": {
"success": false,
"message": "服务器内部错误",
"error_code": "INTERNAL_ERROR"
}
}
]
func _ready():
print("🧪 认证UI测试场景已加载")
# 初始化反馈样式
create_feedback_styles()
# 初始化反馈面板
show_feedback("🎯 测试场景已准备就绪", "info")
add_feedback_line("💡 使用说明:")
add_feedback_line("1⃣ 点击下方测试按钮模拟后端响应")
add_feedback_line("2⃣ 观察左侧认证界面的UI反馈")
add_feedback_line("3⃣ 按ESC键退出测试")
add_feedback_line("")
# 确保auth_scene已准备好
if auth_scene == null:
show_feedback("❌ 错误无法找到AuthScene节点", "error")
return
# 等待一帧确保所有节点都已初始化
await get_tree().process_frame
setup_test_buttons()
# 断开auth_scene的login_success信号避免跳转到主场景
if auth_scene.has_signal("login_success"):
var connections = auth_scene.get_signal_connection_list("login_success")
for connection in connections:
auth_scene.disconnect("login_success", connection.callable)
add_feedback_line("🔗 已断开login_success信号连接")
# 创建反馈样式
func create_feedback_styles():
# 成功样式 - 绿色
var success_style = StyleBoxFlat.new()
success_style.bg_color = Color(0.2, 0.8, 0.3, 0.9)
success_style.border_color = Color(0.1, 0.6, 0.2, 1)
success_style.border_width_left = 2
success_style.border_width_top = 2
success_style.border_width_right = 2
success_style.border_width_bottom = 2
success_style.corner_radius_top_left = 8
success_style.corner_radius_top_right = 8
success_style.corner_radius_bottom_left = 8
success_style.corner_radius_bottom_right = 8
# 错误样式 - 红色
var error_style = StyleBoxFlat.new()
error_style.bg_color = Color(0.8, 0.2, 0.2, 0.9)
error_style.border_color = Color(0.6, 0.1, 0.1, 1)
error_style.border_width_left = 2
error_style.border_width_top = 2
error_style.border_width_right = 2
error_style.border_width_bottom = 2
error_style.corner_radius_top_left = 8
error_style.corner_radius_top_right = 8
error_style.corner_radius_bottom_left = 8
error_style.corner_radius_bottom_right = 8
# 信息样式 - 蓝色
var info_style = StyleBoxFlat.new()
info_style.bg_color = Color(0.2, 0.5, 0.8, 0.9)
info_style.border_color = Color(0.1, 0.4, 0.6, 1)
info_style.border_width_left = 2
info_style.border_width_top = 2
info_style.border_width_right = 2
info_style.border_width_bottom = 2
info_style.corner_radius_top_left = 8
info_style.corner_radius_top_right = 8
info_style.corner_radius_bottom_left = 8
info_style.corner_radius_bottom_right = 8
feedback_styles = {
"success": success_style,
"error": error_style,
"info": info_style
}
func setup_test_buttons():
# 创建测试按钮
for i in range(test_scenarios.size()):
var scenario = test_scenarios[i]
var button = Button.new()
button.text = scenario.name
button.custom_minimum_size.y = 35
button.pressed.connect(_on_test_button_pressed.bind(scenario))
# 为按钮添加样式
var style_normal = StyleBoxFlat.new()
style_normal.bg_color = Color(0.9, 0.9, 0.9, 1)
style_normal.border_color = Color(0.7, 0.7, 0.7, 1)
style_normal.border_width_left = 1
style_normal.border_width_top = 1
style_normal.border_width_right = 1
style_normal.border_width_bottom = 1
style_normal.corner_radius_top_left = 4
style_normal.corner_radius_top_right = 4
style_normal.corner_radius_bottom_left = 4
style_normal.corner_radius_bottom_right = 4
var style_hover = style_normal.duplicate()
style_hover.bg_color = Color(0.8, 0.8, 0.8, 1)
button.add_theme_stylebox_override("normal", style_normal)
button.add_theme_stylebox_override("hover", style_hover)
button.add_theme_color_override("font_color", Color(0.2, 0.2, 0.2, 1))
test_buttons.add_child(button)
# 添加分隔符每4个按钮一组
if (i + 1) % 4 == 0 and i < test_scenarios.size() - 1:
var separator = HSeparator.new()
separator.custom_minimum_size.y = 10
test_buttons.add_child(separator)
add_feedback_line("✨ 已创建 %d 个测试按钮" % test_scenarios.size())
func _on_test_button_pressed(scenario: Dictionary):
# 显示测试开始信息
show_feedback("🚀 执行测试: %s" % scenario.name, "info")
add_feedback_line("📡 请求类型: %s" % scenario.type)
add_feedback_line("📊 状态码: %d" % scenario.response_code)
# 确保auth_scene存在
if auth_scene == null:
show_feedback("❌ 错误AuthScene节点不存在", "error")
return
# 模拟HTTP响应
simulate_http_response(scenario)
func simulate_http_response(scenario: Dictionary):
# 设置当前请求类型
auth_scene.current_request_type = scenario.type
# 准备模拟数据
var response_code = scenario.response_code
var response_data = scenario.response_data
var response_text = JSON.stringify(response_data)
var response_body = response_text.to_utf8_buffer()
var headers = PackedStringArray()
add_feedback_line("⚡ 模拟HTTP响应...")
# 模拟HTTP请求完成
auth_scene._on_http_request_completed(0, response_code, headers, response_body)
# 分析响应结果
analyze_response(scenario, response_data)
func analyze_response(scenario: Dictionary, response_data: Dictionary):
var response_code = scenario.response_code
var is_success = response_code >= 200 and response_code < 300
# 显示响应分析
if is_success:
show_feedback("✅ 测试完成 - 成功响应", "success")
else:
show_feedback("❌ 测试完成 - 错误响应", "error")
# 显示详细信息
if response_data.has("message"):
add_feedback_line("💬 响应消息: %s" % response_data.message)
if response_data.has("error_code"):
add_feedback_line("🏷️ 错误代码: %s" % response_data.error_code)
if response_data.has("data"):
add_feedback_line("📦 响应数据: %s" % str(response_data.data))
# 预期的UI反馈
var expected_feedback = get_expected_ui_feedback(scenario)
add_feedback_line("🎯 预期UI反馈: %s" % expected_feedback)
add_feedback_line("─────────────────────")
func get_expected_ui_feedback(scenario: Dictionary) -> String:
var response_code = scenario.response_code
var type = scenario.type
match type:
"login":
match response_code:
200:
return "绿色Toast: 登录成功,跳转到主场景"
400:
return "红色Toast: 登录信息格式错误"
401:
return "红色Toast: 用户名或密码错误"
404:
return "红色Toast: 用户不存在"
429:
return "红色Toast: 登录请求过于频繁"
500:
return "红色Toast: 服务器繁忙"
"send_code":
match response_code:
200, 206:
return "绿色Toast: 验证码已发送"
400:
return "红色Toast: 邮箱格式错误"
429:
return "红色Toast: 请求过于频繁"
500:
return "红色Toast: 服务器繁忙"
0:
return "红色Toast: 网络连接失败"
"verify_email":
match response_code:
200:
return "绿色Toast: 邮箱验证成功"
400:
return "红色Toast: 验证码错误"
404:
return "红色Toast: 请先获取验证码"
500:
return "红色Toast: 验证失败"
"register":
match response_code:
201:
return "绿色Toast: 注册成功,切换到登录界面"
400:
return "红色Toast: 根据具体错误显示(验证码缺失、格式错误等)"
409:
return "红色Toast: 用户名或邮箱已存在"
429:
return "红色Toast: 注册请求过于频繁,请稍后再试"
500:
return "红色Toast: 注册失败"
return "未知响应"
# 反馈面板功能
func show_feedback(message: String, type: String = "info"):
# 更改面板样式
if feedback_styles.has(type):
feedback_panel.add_theme_stylebox_override("panel", feedback_styles[type])
# 清空并显示新消息
feedback_text.text = "[b]%s[/b]" % message
func add_feedback_line(message: String):
feedback_text.text += "\n" + message
# 自动滚动到底部
await get_tree().process_frame
var scroll = feedback_text.get_parent()
if scroll is ScrollContainer:
scroll.scroll_vertical = scroll.get_v_scroll_bar().max_value
func _input(event):
if event.is_action_pressed("ui_cancel"):
show_feedback("👋 退出测试场景", "info")
await get_tree().create_timer(0.5).timeout
get_tree().quit()