""" Engine 单元测试 测试游戏引擎核心组件 """ import unittest import sys import os # 添加当前目录到路径 sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from engine import Player, HumanPlayer, AIPlayer, RoomManager, Room from engine.game_base import GameBase, GameState, GamePhase from engine.test_game import TestGame class TestPlayer(unittest.TestCase): """测试 Player 类""" def test_human_player_creation(self): """测试创建人类玩家""" player = HumanPlayer("测试玩家", "player_001") self.assertEqual(player.id, "player_001") self.assertEqual(player.name, "测试玩家") self.assertFalse(player.is_ai) self.assertIsNone(player.room_id) self.assertIsNone(player.seat_number) def test_ai_player_creation(self): """测试创建 AI 玩家""" player = AIPlayer("AI-1", "rule", {"difficulty": "easy"}) self.assertEqual(player.name, "AI-1") self.assertTrue(player.is_ai) self.assertEqual(player.ai_type, "rule") self.assertTrue(player.is_ready) # AI 自动准备 def test_player_connect(self): """测试玩家连接""" player = HumanPlayer("测试玩家") player.connect("socket_123") self.assertEqual(player.socket_id, "socket_123") self.assertTrue(player.is_connected) self.assertIsNotNone(player.connected_at) def test_player_join_room(self): """测试玩家加入房间""" player = HumanPlayer("测试玩家", "player_001") player.join_room("room_001", 0) self.assertEqual(player.room_id, "room_001") self.assertEqual(player.seat_number, 0) def test_player_leave_room(self): """测试玩家离开房间""" player = HumanPlayer("测试玩家", "player_001") player.join_room("room_001", 0) player.leave_room() self.assertIsNone(player.room_id) self.assertIsNone(player.seat_number) def test_player_to_dict(self): """测试玩家序列化""" player = HumanPlayer("测试玩家", "player_001") player.join_room("room_001", 0) player.set_ready(True) data = player.to_dict() self.assertEqual(data['id'], "player_001") self.assertEqual(data['name'], "测试玩家") self.assertEqual(data['seat_number'], 0) self.assertTrue(data['is_ready']) # 测试包含私有信息 data_private = player.to_dict(include_private=True) self.assertEqual(data_private['room_id'], "room_001") class TestRoom(unittest.TestCase): """测试 Room 类""" def test_room_creation(self): """测试创建房间""" room = Room("room_001", "ABC123", "test_game", 3) self.assertEqual(room.id, "room_001") self.assertEqual(room.code, "ABC123") self.assertEqual(room.game_type, "test_game") self.assertEqual(room.max_players, 3) self.assertEqual(room.status, "waiting") def test_add_player(self): """测试添加玩家""" room = Room("room_001", "ABC123", "test_game", 3) player = HumanPlayer("玩家1", "player_001") result = room.add_player(player) self.assertTrue(result) self.assertEqual(room.player_count, 1) self.assertEqual(player.seat_number, 0) self.assertEqual(room.host_id, "player_001") def test_room_full(self): """测试房间满了""" room = Room("room_001", "ABC123", "test_game", 2) player1 = HumanPlayer("玩家1", "player_001") player2 = HumanPlayer("玩家2", "player_002") player3 = HumanPlayer("玩家3", "player_003") room.add_player(player1) room.add_player(player2) self.assertTrue(room.is_full) self.assertFalse(room.add_player(player3)) def test_remove_player(self): """测试移除玩家""" room = Room("room_001", "ABC123", "test_game", 3) player = HumanPlayer("玩家1", "player_001") room.add_player(player) result = room.remove_player("player_001") self.assertTrue(result) self.assertEqual(room.player_count, 0) self.assertIsNone(player.room_id) def test_room_to_dict(self): """测试房间序列化""" room = Room("room_001", "ABC123", "test_game", 3) player = HumanPlayer("玩家1", "player_001") room.add_player(player) data = room.to_dict(include_game_state=False) self.assertEqual(data['id'], "room_001") self.assertEqual(data['code'], "ABC123") self.assertEqual(data['player_count'], 1) self.assertEqual(len(data['players']), 1) class TestRoomManager(unittest.TestCase): """测试 RoomManager 单例""" def setUp(self): """每个测试前清理""" # 重置单例状态 RoomManager._instance = None RoomManager._initialized = False self.manager = RoomManager() self.manager._game_registry['test_game'] = TestGame def test_singleton(self): """测试单例模式""" manager1 = RoomManager() manager2 = RoomManager() self.assertIs(manager1, manager2) def test_create_room(self): """测试创建房间""" room = self.manager.create_room("test_game", 3) self.assertIsNotNone(room) self.assertEqual(room.game_type, "test_game") self.assertEqual(len(room.code), 6) # 验证可以通过 code 获取 room2 = self.manager.get_room(room_code=room.code) self.assertEqual(room2.id, room.id) def test_join_room(self): """测试加入房间""" room = self.manager.create_room("test_game", 3) player = HumanPlayer("玩家1", "player_001") success, message = self.manager.join_room(room.code, player) self.assertTrue(success) self.assertEqual(message, "加入成功") self.assertEqual(room.player_count, 1) def test_join_nonexistent_room(self): """测试加入不存在的房间""" player = HumanPlayer("玩家1", "player_001") success, message = self.manager.join_room("ZZZZZZ", player) self.assertFalse(success) self.assertEqual(message, "房间不存在") def test_leave_room(self): """测试离开房间""" room = self.manager.create_room("test_game", 3) player = HumanPlayer("玩家1", "player_001") self.manager.join_room(room.code, player) result = self.manager.leave_room("player_001") self.assertTrue(result) self.assertEqual(room.player_count, 0) def test_start_game(self): """测试开始游戏""" room = self.manager.create_room("test_game", 3) player = HumanPlayer("玩家1", "player_001") self.manager.join_room(room.code, player) success, message = self.manager.start_game(room.id) self.assertTrue(success) self.assertEqual(room.status, "playing") self.assertIsNotNone(room.game) class TestTestGame(unittest.TestCase): """测试 TestGame 示例游戏""" def setUp(self): """设置测试游戏""" self.game = TestGame("room_001", "test_game") self.player1 = HumanPlayer("玩家1", "player_001") self.player2 = HumanPlayer("玩家2", "player_002") self.game.add_player(self.player1) self.game.add_player(self.player2) def test_game_properties(self): """测试游戏属性""" self.assertEqual(self.game.min_players, 1) self.assertEqual(self.game.max_players, 4) self.assertEqual(self.game.player_count, 2) self.assertTrue(self.game.can_start()) def test_start_game(self): """测试开始游戏""" self.game.start() self.assertTrue(self.game.is_started) self.assertEqual(self.game.state.phase, GamePhase.PLAYING) self.assertIsNotNone(self.game.target_number) self.assertIsNotNone(self.game.state.current_turn_player_id) def test_guess_too_small(self): """测试猜测太小""" self.game.start() self.game.target_number = 50 # 固定目标 result = self.game.handle_action("player_001", "guess", {"number": 30}) self.assertTrue(result['success']) self.assertEqual(result['result'], 'too_small') self.assertIn('太小了', result['message']) def test_guess_too_large(self): """测试猜测太大""" self.game.start() self.game.target_number = 50 result = self.game.handle_action("player_001", "guess", {"number": 70}) self.assertTrue(result['success']) self.assertEqual(result['result'], 'too_large') def test_guess_correct(self): """测试猜中""" self.game.start() self.game.target_number = 50 result = self.game.handle_action("player_001", "guess", {"number": 50}) self.assertTrue(result['success']) self.assertEqual(result['result'], 'correct') self.assertTrue(self.game.is_ended) self.assertEqual(self.game.state.winner_id, "player_001") def test_wrong_turn(self): """测试非当前玩家操作""" self.game.start() # 假设 player_002 不是当前回合 if self.game.state.current_turn_player_id == "player_001": result = self.game.handle_action("player_002", "guess", {"number": 50}) self.assertFalse(result['success']) self.assertIn('不是你的回合', result['message']) def test_invalid_guess(self): """测试无效猜测""" self.game.start() result = self.game.handle_action("player_001", "guess", {"number": 150}) self.assertFalse(result['success']) self.assertIn('1-100', result['message']) def test_game_to_dict(self): """测试游戏序列化""" self.game.start() data = self.game.to_dict() self.assertEqual(data['game_type'], 'test_game') self.assertIn('state', data) # 目标数字不应暴露给客户端 self.assertNotIn('target', data['state'].get('data', {})) class TestGameState(unittest.TestCase): """测试 GameState 类""" def test_state_creation(self): """测试状态创建""" state = GameState("test_game", "room_001") self.assertEqual(state.game_type, "test_game") self.assertEqual(state.room_id, "room_001") self.assertEqual(state.phase, GamePhase.WAITING) self.assertEqual(state.round, 0) def test_state_start(self): """测试开始状态""" state = GameState("test_game", "room_001") state.start() self.assertEqual(state.phase, GamePhase.PLAYING) self.assertEqual(state.round, 1) self.assertIsNotNone(state.started_at) def test_state_end(self): """测试结束状态""" state = GameState("test_game", "room_001") state.start() state.end("player_001") self.assertEqual(state.phase, GamePhase.ENDED) self.assertEqual(state.winner_id, "player_001") self.assertIsNotNone(state.ended_at) def test_next_turn(self): """测试切换回合""" state = GameState("test_game", "room_001") state.next_turn("player_001") self.assertEqual(state.current_turn_player_id, "player_001") self.assertEqual(state.turn_count, 1) def test_add_history(self): """测试添加历史""" state = GameState("test_game", "room_001") state.add_history("guess", "player_001", {"number": 50}) self.assertEqual(len(state.history), 1) self.assertEqual(state.history[0]['action'], "guess") class IntegrationTest(unittest.TestCase): """集成测试""" def setUp(self): """重置单例""" RoomManager._instance = None RoomManager._initialized = False self.manager = RoomManager() self.manager._game_registry['test_game'] = TestGame def test_full_game_flow(self): """测试完整游戏流程""" # 1. 创建房间 room = self.manager.create_room("test_game", 2) self.assertIsNotNone(room) # 2. 玩家1加入 player1 = HumanPlayer("玩家1", "p1") success, _ = self.manager.join_room(room.code, player1) self.assertTrue(success) # 3. 玩家2加入 player2 = HumanPlayer("玩家2", "p2") success, _ = self.manager.join_room(room.code, player2) self.assertTrue(success) # 4. 开始游戏 success, _ = self.manager.start_game(room.id) self.assertTrue(success) # 5. 获取游戏 game = room.game self.assertIsNotNone(game) game.target_number = 50 # 固定目标便于测试 # 6. 玩家1猜测 result = game.handle_action("p1", "guess", {"number": 30}) self.assertTrue(result['success']) # 7. 玩家2猜测(正确) result = game.handle_action("p2", "guess", {"number": 50}) self.assertTrue(result['success']) self.assertEqual(result['result'], 'correct') # 8. 游戏结束 self.assertTrue(game.is_ended) self.assertEqual(game.state.winner_id, "p2") def run_tests(): """运行所有测试""" loader = unittest.TestLoader() suite = unittest.TestSuite() # 添加所有测试类 suite.addTests(loader.loadTestsFromTestCase(TestPlayer)) suite.addTests(loader.loadTestsFromTestCase(TestRoom)) suite.addTests(loader.loadTestsFromTestCase(TestRoomManager)) suite.addTests(loader.loadTestsFromTestCase(TestTestGame)) suite.addTests(loader.loadTestsFromTestCase(TestGameState)) suite.addTests(loader.loadTestsFromTestCase(IntegrationTest)) # 运行测试 runner = unittest.TextTestRunner(verbosity=2) result = runner.run(suite) return result.wasSuccessful() if __name__ == '__main__': success = run_tests() sys.exit(0 if success else 1)