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