Files
nanocode/net-games/test_engine.py
T
Ubuntu 32b43f85bd a
2026-07-03 16:58:28 +08:00

433 lines
14 KiB
Python

"""
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)