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")