创建新工程
This commit is contained in:
203
tests/test_property_server_sync.gd
Normal file
203
tests/test_property_server_sync.gd
Normal file
@@ -0,0 +1,203 @@
|
||||
extends Node
|
||||
## 服务器更新同步属性测试
|
||||
## Feature: godot-ai-town-game, Property 30: 服务器更新同步
|
||||
|
||||
const TEST_ITERATIONS = 50
|
||||
|
||||
# 测试结果统计
|
||||
var test_results = {
|
||||
"passed": 0,
|
||||
"failed": 0,
|
||||
"errors": []
|
||||
}
|
||||
|
||||
func _ready():
|
||||
print("\n=== Property Test: Server Update Synchronization ===")
|
||||
await test_property_server_update_sync()
|
||||
print_results()
|
||||
print("=== Property Test Completed ===\n")
|
||||
|
||||
## Feature: godot-ai-town-game, Property 30: 服务器更新同步
|
||||
func test_property_server_update_sync():
|
||||
"""
|
||||
属性测试:服务器更新同步
|
||||
对于任意服务器推送的更新消息,客户端应该实时更新本地游戏状态以反映服务器的变化
|
||||
|
||||
本测试验证:
|
||||
1. 消息协议的序列化/反序列化正确性
|
||||
2. 不同类型消息的数据完整性
|
||||
3. 消息格式的有效性
|
||||
|
||||
验证需求: 12.5
|
||||
"""
|
||||
print("\n[Property Test] Testing server update synchronization...")
|
||||
print("Running ", TEST_ITERATIONS, " iterations...")
|
||||
|
||||
# 测试不同类型的服务器更新消息
|
||||
var message_types = [
|
||||
MessageProtocol.MessageType.CHARACTER_MOVE,
|
||||
MessageProtocol.MessageType.CHARACTER_STATE,
|
||||
MessageProtocol.MessageType.WORLD_STATE
|
||||
]
|
||||
|
||||
for i in range(TEST_ITERATIONS):
|
||||
# 随机选择消息类型
|
||||
var msg_type = message_types[randi() % message_types.size()]
|
||||
|
||||
# 生成随机测试数据
|
||||
var original_message = _generate_test_message(msg_type)
|
||||
|
||||
# 模拟服务器发送:序列化消息
|
||||
var serialized = MessageProtocol.serialize(original_message)
|
||||
|
||||
# 模拟客户端接收:反序列化消息
|
||||
var received_message = MessageProtocol.deserialize(serialized)
|
||||
|
||||
await get_tree().process_frame
|
||||
|
||||
# 验证消息是否正确接收
|
||||
if received_message.is_empty():
|
||||
test_results["failed"] += 1
|
||||
test_results["errors"].append({
|
||||
"iteration": i + 1,
|
||||
"type": "deserialization_failed",
|
||||
"original": original_message,
|
||||
"serialized": serialized
|
||||
})
|
||||
continue
|
||||
|
||||
# 验证消息格式
|
||||
if not MessageProtocol.validate_message(received_message):
|
||||
test_results["failed"] += 1
|
||||
test_results["errors"].append({
|
||||
"iteration": i + 1,
|
||||
"type": "invalid_message_format",
|
||||
"message": received_message
|
||||
})
|
||||
continue
|
||||
|
||||
# 验证数据完整性
|
||||
var data_matches = _verify_message_data(original_message, received_message)
|
||||
|
||||
if data_matches:
|
||||
test_results["passed"] += 1
|
||||
else:
|
||||
test_results["failed"] += 1
|
||||
test_results["errors"].append({
|
||||
"iteration": i + 1,
|
||||
"type": "data_mismatch",
|
||||
"expected": original_message,
|
||||
"actual": received_message
|
||||
})
|
||||
|
||||
func _generate_test_message(msg_type: MessageProtocol.MessageType) -> Dictionary:
|
||||
"""生成测试消息"""
|
||||
var data = {}
|
||||
|
||||
match msg_type:
|
||||
MessageProtocol.MessageType.CHARACTER_MOVE:
|
||||
data = {
|
||||
"character_id": "char_" + str(randi()),
|
||||
"position": {
|
||||
"x": randf_range(0, 1000),
|
||||
"y": randf_range(0, 1000)
|
||||
},
|
||||
"direction": {
|
||||
"x": randf_range(-1, 1),
|
||||
"y": randf_range(-1, 1)
|
||||
}
|
||||
}
|
||||
|
||||
MessageProtocol.MessageType.CHARACTER_STATE:
|
||||
data = {
|
||||
"character_id": "char_" + str(randi()),
|
||||
"is_online": randi() % 2 == 0,
|
||||
"position": {
|
||||
"x": randf_range(0, 1000),
|
||||
"y": randf_range(0, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
MessageProtocol.MessageType.WORLD_STATE:
|
||||
var num_characters = randi() % 5 + 1
|
||||
var characters = []
|
||||
for j in range(num_characters):
|
||||
characters.append({
|
||||
"id": "char_" + str(j),
|
||||
"name": "Character" + str(j),
|
||||
"position": {
|
||||
"x": randf_range(0, 1000),
|
||||
"y": randf_range(0, 1000)
|
||||
},
|
||||
"is_online": randi() % 2 == 0
|
||||
})
|
||||
data = {
|
||||
"characters": characters
|
||||
}
|
||||
|
||||
return MessageProtocol.create_message(msg_type, data)
|
||||
|
||||
func _verify_message_data(expected: Dictionary, actual: Dictionary) -> bool:
|
||||
"""验证消息数据是否匹配"""
|
||||
# 验证消息类型
|
||||
if expected.get("type") != actual.get("type"):
|
||||
print(" Type mismatch: ", expected.get("type"), " vs ", actual.get("type"))
|
||||
return false
|
||||
|
||||
# 验证数据字段存在
|
||||
if not actual.has("data"):
|
||||
print(" Missing data field")
|
||||
return false
|
||||
|
||||
# 基本验证:检查关键字段
|
||||
var expected_data = expected.get("data", {})
|
||||
var actual_data = actual.get("data", {})
|
||||
|
||||
# 根据消息类型验证特定字段
|
||||
var msg_type_str = expected.get("type")
|
||||
|
||||
if msg_type_str == "character_move":
|
||||
var char_id_match = expected_data.get("character_id") == actual_data.get("character_id")
|
||||
var pos_match = _compare_positions(expected_data.get("position"), actual_data.get("position"))
|
||||
return char_id_match and pos_match
|
||||
|
||||
elif msg_type_str == "character_state":
|
||||
var char_id_match = expected_data.get("character_id") == actual_data.get("character_id")
|
||||
var online_match = expected_data.get("is_online") == actual_data.get("is_online")
|
||||
return char_id_match and online_match
|
||||
|
||||
elif msg_type_str == "world_state":
|
||||
var expected_chars = expected_data.get("characters", [])
|
||||
var actual_chars = actual_data.get("characters", [])
|
||||
return expected_chars.size() == actual_chars.size()
|
||||
|
||||
return true
|
||||
|
||||
func _compare_positions(pos1: Dictionary, pos2: Dictionary) -> bool:
|
||||
"""比较两个位置是否相近"""
|
||||
if not pos1 or not pos2:
|
||||
return false
|
||||
|
||||
var x1 = pos1.get("x", 0.0)
|
||||
var y1 = pos1.get("y", 0.0)
|
||||
var x2 = pos2.get("x", 0.0)
|
||||
var y2 = pos2.get("y", 0.0)
|
||||
|
||||
return abs(x1 - x2) < 0.01 and abs(y1 - y2) < 0.01
|
||||
|
||||
func print_results():
|
||||
"""打印测试结果"""
|
||||
print("\n=== Test Results ===")
|
||||
print("Total iterations: ", TEST_ITERATIONS)
|
||||
print("Passed: ", test_results["passed"])
|
||||
print("Failed: ", test_results["failed"])
|
||||
|
||||
if test_results["failed"] > 0:
|
||||
print("\n❌ FAILED: Some iterations failed")
|
||||
print("First 5 errors:")
|
||||
for i in range(min(5, test_results["errors"].size())):
|
||||
var error = test_results["errors"][i]
|
||||
print(" Error ", i + 1, ": ", error)
|
||||
else:
|
||||
print("\n✅ PASSED: All server updates synchronized correctly")
|
||||
print("Property 30 validated: Server updates are properly received and processed")
|
||||
Reference in New Issue
Block a user