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

227 lines
8.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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.

#!/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"])