创建新工程
This commit is contained in:
168
tests/test_property_offline_characters.gd
Normal file
168
tests/test_property_offline_characters.gd
Normal file
@@ -0,0 +1,168 @@
|
||||
extends Node
|
||||
## 离线角色显示属性测试
|
||||
## Feature: godot-ai-town-game, Property 23: 离线角色显示
|
||||
|
||||
const TEST_ITERATIONS = 50
|
||||
|
||||
# 测试结果统计
|
||||
var test_results = {
|
||||
"passed": 0,
|
||||
"failed": 0,
|
||||
"errors": []
|
||||
}
|
||||
|
||||
func _ready():
|
||||
print("\n=== Property Test: Offline Character Display ===")
|
||||
await test_property_offline_character_display()
|
||||
print_results()
|
||||
print("=== Property Test Completed ===\n")
|
||||
|
||||
## Feature: godot-ai-town-game, Property 23: 离线角色显示
|
||||
func test_property_offline_character_display():
|
||||
"""
|
||||
属性测试:离线角色显示
|
||||
对于任意玩家进入游戏场景时,系统应该显示所有离线玩家的角色作为 NPC
|
||||
|
||||
验证需求: 11.2
|
||||
"""
|
||||
print("\n[Property Test] Testing offline character display...")
|
||||
print("Running ", TEST_ITERATIONS, " iterations...")
|
||||
|
||||
for i in range(TEST_ITERATIONS):
|
||||
# 创建世界管理器和角色容器
|
||||
var world_manager = WorldManager.new()
|
||||
var character_container = Node2D.new()
|
||||
character_container.name = "CharacterContainer"
|
||||
|
||||
add_child(world_manager)
|
||||
add_child(character_container)
|
||||
|
||||
world_manager.set_character_container(character_container)
|
||||
|
||||
await get_tree().process_frame
|
||||
|
||||
# 生成随机数量的离线角色
|
||||
var num_offline_characters = randi() % 5 + 1 # 1-5 个离线角色
|
||||
var spawned_characters = []
|
||||
|
||||
for j in range(num_offline_characters):
|
||||
var character_data = _generate_offline_character_data(j)
|
||||
var character = world_manager.spawn_character(character_data, false)
|
||||
|
||||
if character:
|
||||
spawned_characters.append({
|
||||
"id": character_data[CharacterData.FIELD_ID],
|
||||
"character": character
|
||||
})
|
||||
|
||||
await get_tree().process_frame
|
||||
|
||||
# 验证所有离线角色都被正确显示为 NPC
|
||||
var all_displayed = true
|
||||
var display_errors = []
|
||||
|
||||
for char_info in spawned_characters:
|
||||
var char_id = char_info["id"]
|
||||
var character = char_info["character"]
|
||||
|
||||
# 检查角色是否在场景树中
|
||||
if not is_instance_valid(character):
|
||||
all_displayed = false
|
||||
display_errors.append({
|
||||
"character_id": char_id,
|
||||
"error": "character_not_valid"
|
||||
})
|
||||
continue
|
||||
|
||||
if not character.is_inside_tree():
|
||||
all_displayed = false
|
||||
display_errors.append({
|
||||
"character_id": char_id,
|
||||
"error": "not_in_scene_tree"
|
||||
})
|
||||
continue
|
||||
|
||||
# 检查角色是否标记为离线
|
||||
if character.is_online:
|
||||
all_displayed = false
|
||||
display_errors.append({
|
||||
"character_id": char_id,
|
||||
"error": "marked_as_online_instead_of_offline"
|
||||
})
|
||||
continue
|
||||
|
||||
# 检查角色是否可见(离线角色应该作为 NPC 显示)
|
||||
if not character.visible:
|
||||
all_displayed = false
|
||||
display_errors.append({
|
||||
"character_id": char_id,
|
||||
"error": "not_visible"
|
||||
})
|
||||
|
||||
# 验证离线角色仍然存在于世界中(不应被移除)
|
||||
var managed_char = world_manager.get_character(char_id)
|
||||
if not managed_char:
|
||||
all_displayed = false
|
||||
display_errors.append({
|
||||
"character_id": char_id,
|
||||
"error": "not_managed_by_world_manager"
|
||||
})
|
||||
|
||||
# 验证世界管理器中记录的角色数量
|
||||
var managed_characters = world_manager.get_all_characters()
|
||||
if managed_characters.size() != num_offline_characters:
|
||||
all_displayed = false
|
||||
display_errors.append({
|
||||
"error": "character_count_mismatch",
|
||||
"expected": num_offline_characters,
|
||||
"actual": managed_characters.size()
|
||||
})
|
||||
|
||||
if all_displayed:
|
||||
test_results["passed"] += 1
|
||||
else:
|
||||
test_results["failed"] += 1
|
||||
test_results["errors"].append({
|
||||
"iteration": i + 1,
|
||||
"num_characters": num_offline_characters,
|
||||
"errors": display_errors
|
||||
})
|
||||
|
||||
# 清理
|
||||
world_manager.clear_all_characters()
|
||||
world_manager.queue_free()
|
||||
character_container.queue_free()
|
||||
await get_tree().process_frame
|
||||
|
||||
func _generate_offline_character_data(index: int) -> Dictionary:
|
||||
"""生成离线角色数据"""
|
||||
var character_data = CharacterData.create(
|
||||
"OfflinePlayer" + str(index),
|
||||
"owner_" + str(index),
|
||||
Vector2(randf_range(100, 900), randf_range(100, 700))
|
||||
)
|
||||
|
||||
# 确保角色标记为离线
|
||||
character_data[CharacterData.FIELD_IS_ONLINE] = false
|
||||
|
||||
# 设置最后在线时间(模拟之前在线过)
|
||||
character_data[CharacterData.FIELD_LAST_SEEN] = Time.get_unix_time_from_system() - randf_range(3600, 86400)
|
||||
|
||||
return character_data
|
||||
|
||||
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 offline characters displayed correctly as NPCs")
|
||||
print("Property 23 validated: Offline characters persist in the world as NPCs")
|
||||
Reference in New Issue
Block a user