kards-env/tests/test_yaml_unit_loader.py.di...

227 lines
8.1 KiB
Plaintext
Raw Permalink Normal View History

2025-09-05 17:05:43 +08:00
#!/usr/bin/env python3
"""
YAML单位加载器测试
测试YAML单位定义系统的各种功能
"""
import pytest
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from kards_battle.units.unit_loader import UnitLoader, load_unit, list_all_units, get_unit_loader
from kards_battle.units.unit import Unit
from kards_battle.core.enums import UnitType
class TestUnitLoader:
"""测试单位加载器"""
def setup_method(self):
"""每个测试前的设置"""
# 创建独立的加载器实例
self.loader = UnitLoader()
def test_load_all_units_from_assets(self):
"""测试从assets目录加载所有单位"""
units_data = self.loader.load_all_units()
# 验证加载了正确数量的单位
assert len(units_data) > 0, "应该加载至少一个单位"
# 验证德军和美军单位都存在
german_units = [uid for uid in units_data.keys() if uid.startswith('ger_')]
usa_units = [uid for uid in units_data.keys() if uid.startswith('usa_')]
assert len(german_units) > 0, "应该有德军单位"
assert len(usa_units) > 0, "应该有美军单位"
def test_create_unit_from_yaml_data(self):
"""测试从YAML数据创建单位实例"""
self.loader.load_all_units()
# 测试德军步兵
unit = self.loader.create_unit_from_id("ger_infantry_grenadier")
assert isinstance(unit, Unit)
assert unit.name == "German Grenadier"
assert unit.unit_type == UnitType.INFANTRY
assert unit.stats.attack == 2
assert unit.stats.defense == 1
assert unit.stats.operation_cost == 1
assert unit.nation == "GERMANY"
assert unit.definition_id == "ger_infantry_grenadier"
def test_unit_with_keywords(self):
"""测试:带关键词的单位加载"""
self.loader.load_all_units()
# 测试带BLITZ关键词的单位
unit = self.loader.create_unit_from_id("ger_infantry_15th_cavalry")
assert "BLITZ" in unit.keywords
assert unit.name == "15th Cavalry Regiment"
def test_different_unit_types(self):
"""测试:不同类型的单位加载"""
self.loader.load_all_units()
# 测试步兵
infantry = self.loader.create_unit_from_id("ger_infantry_grenadier")
assert infantry.unit_type == UnitType.INFANTRY
# 测试坦克
tank = self.loader.create_unit_from_id("ger_tank_panzer_iv")
assert tank.unit_type == UnitType.TANK
assert "BLITZ" in tank.keywords
# 测试火炮
artillery = self.loader.create_unit_from_id("ger_artillery_88mm")
assert artillery.unit_type == UnitType.ARTILLERY
assert "GUARD" in artillery.keywords
# 测试战斗机
fighter = self.loader.create_unit_from_id("ger_fighter_bf109")
assert fighter.unit_type == UnitType.FIGHTER
# 测试轰炸机
bomber = self.loader.create_unit_from_id("ger_bomber_stuka")
assert bomber.unit_type == UnitType.BOMBER
def test_units_by_nation(self):
"""测试:按国家获取单位"""
self.loader.load_all_units()
german_units = self.loader.get_units_by_nation("GERMANY")
usa_units = self.loader.get_units_by_nation("USA")
assert len(german_units) > 0
assert len(usa_units) > 0
# 验证国家分类正确
for unit_data in german_units:
assert unit_data['nation'] == 'GERMANY'
for unit_data in usa_units:
assert unit_data['nation'] == 'USA'
def test_units_by_type(self):
"""测试:按类型获取单位"""
self.loader.load_all_units()
infantry_units = self.loader.get_units_by_type("INFANTRY")
tank_units = self.loader.get_units_by_type("TANK")
assert len(infantry_units) > 0
assert len(tank_units) > 0
# 验证类型分类正确
for unit_data in infantry_units:
assert unit_data['type'].upper() == 'INFANTRY'
def test_invalid_unit_id(self):
"""测试无效单位ID处理"""
self.loader.load_all_units()
with pytest.raises(ValueError, match="Unit definition not found"):
self.loader.create_unit_from_id("invalid_unit_id")
def test_backward_compatibility_activation_cost(self):
"""测试activation_cost属性向后兼容性"""
unit = load_unit("ger_infantry_grenadier")
# 验证可以通过stats.operation_cost访问
assert unit.stats.operation_cost == 1
# 验证新的YAML单位正确设置了operation_cost
assert hasattr(unit.stats, 'operation_cost')
def test_unit_abilities_loading(self):
"""测试:单位能力的加载"""
self.loader.load_all_units()
# 测试带能力的轰炸机
bomber = self.loader.create_unit_from_id("ger_bomber_stuka")
assert len(bomber.abilities) > 0, "斯图卡应该有部署能力"
# 测试带能力的火炮
artillery = self.loader.create_unit_from_id("ger_artillery_nebelwerfer")
assert len(artillery.abilities) > 0, "火箭炮应该有特殊能力"
class TestGlobalFunctions:
"""测试全局便捷函数"""
def test_global_load_unit(self):
"""测试全局load_unit函数"""
unit = load_unit("usa_infantry_gi")
assert isinstance(unit, Unit)
assert unit.name == "American GI"
assert unit.unit_type == UnitType.INFANTRY
assert unit.nation == "USA"
def test_global_list_all_units(self):
"""测试全局list_all_units函数"""
units = list_all_units()
assert isinstance(units, list)
assert len(units) > 0
assert "ger_infantry_grenadier" in units
assert "usa_infantry_gi" in units
def test_global_loader_singleton(self):
"""测试:全局加载器单例模式"""
loader1 = get_unit_loader()
loader2 = get_unit_loader()
assert loader1 is loader2, "应该返回同一个单例实例"
class TestYAMLIntegration:
"""测试YAML系统与游戏引擎的集成"""
def test_yaml_unit_in_battle_engine(self):
"""测试YAML单位在战斗引擎中的使用"""
from kards_battle.core.battle_engine import BattleEngine
engine = BattleEngine("Germany", "USA", debug_mode=True)
# 使用YAML单位
unit = load_unit("ger_infantry_grenadier")
# 部署单位
result = engine.deploy_unit_to_support(unit, 0)
assert result['success']
# 验证单位正确部署
support_units = engine.battlefield.player1_support.get_all_units()
assert len(support_units) == 1
assert support_units[0].name == "German Grenadier"
def test_yaml_unit_movement_costs(self):
"""测试YAML单位的移动成本"""
from kards_battle.core.battle_engine import BattleEngine
engine = BattleEngine("Germany", "USA", debug_mode=True)
# 使用不同成本的YAML单位
cheap_unit = load_unit("ger_infantry_grenadier") # cost=1
expensive_unit = load_unit("ger_tank_tiger") # cost=4
engine.deploy_unit_to_support(cheap_unit, 0)
engine.deploy_unit_to_support(expensive_unit, 0)
# 测试便宜单位可以移动
from kards_battle.core.enums import LineType
engine.debug_set_kredits(0, kredits=2)
result1 = engine.move_unit(cheap_unit.id, (LineType.FRONT, 0), 0)
assert result1['success']
# 测试昂贵单位费用不足时不能移动
result2 = engine.move_unit(expensive_unit.id, (LineType.FRONT, 1), 0)
assert not result2['success']
assert "Insufficient Kredits" in result2['reason']
if __name__ == "__main__":
pytest.main([__file__, "-v"])