Files
whale-town-front/tests/auth/auth_ui_test.gd
moyin 47cfc14f68 test:添加认证系统测试套件
- 添加UI测试场景,支持模拟各种认证场景
- 实现API测试脚本,覆盖登录、注册、验证码等接口
- 添加测试文档,说明测试用例和预期结果
- 支持自动化测试和手动测试验证
2025-12-24 20:37:33 +08:00

465 lines
13 KiB
GDScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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()