/
MetCode
/
Arkanoid_for_human
Обзор
Документация
Войти
/
MetCode
/
Arkanoid_for_human
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
tests/test_interface_improvements.py
351 строка
14 KB
mxchgeCode
Исправлена анимация победы: теперь показывается при обычной победе (все кирпичи уничтожены)
13 дек 2025, 07:33
13 дек 2025, 07:33
84a1b96
Код
Авторство
О чём код?
#!/usr/bin/env python3 """ Тест для проверки улучшений интерфейса игры """ import sys import os from typing import List, Dict, Any, Optional # Добавляем родительскую директорию в путь для импорта модулей parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, parent_dir) from game.highscores import HighScoreManager import json def test_highscores_display_logic() -> bool: """Тестирует логику отображения таблицы рекордов""" print("=" * 60) print("ТЕСТ ЛОГИКИ ОТОБРАЖЕНИЯ ТАБЛИЦЫ РЕКОРДОВ") print("=" * 60) # Создаем временный файл с рекордами для тестирования test_scores: List[Dict[str, Any]] = [ { "player_name": "TestPlayer1", "score": 50, "time_seconds": 30, "time_formatted": "0:30", "date": "2025-11-28 19:00", }, { "player_name": "TestPlayer2", "score": 45, "time_seconds": 45, "time_formatted": "0:45", "date": "2025-11-28 19:01", }, { "player_name": "TestPlayer3", "score": 40, "time_seconds": 60, "time_formatted": "1:00", "date": "2025-11-28 19:02", }, { "player_name": "TestPlayer4", "score": 35, "time_seconds": 90, "time_formatted": "1:30", "date": "2025-11-28 19:03", }, { "player_name": "TestPlayer5", "score": 30, "time_seconds": 120, "time_formatted": "2:00", "date": "2025-11-28 19:04", }, { "player_name": "TestPlayer6", "score": 25, "time_seconds": 150, "time_formatted": "2:30", "date": "2025-11-28 19:05", }, { "player_name": "TestPlayer7", "score": 20, "time_seconds": 180, "time_formatted": "3:00", "date": "2025-11-28 19:06", }, { "player_name": "TestPlayer8", "score": 15, "time_seconds": 210, "time_formatted": "3:30", "date": "2025-11-28 19:07", }, { "player_name": "TestPlayer9", "score": 10, "time_seconds": 240, "time_formatted": "4:00", "date": "2025-11-28 19:08", }, { "player_name": "TestPlayer10", "score": 5, "time_seconds": 270, "time_formatted": "4:30", "date": "2025-11-28 19:09", }, ] # Сохраняем тестовые данные with open("test_highscores.json", "w", encoding="utf-8") as f: json.dump(test_scores, f, ensure_ascii=False, indent=2) try: # Создаем менеджер с тестовыми данными from game.highscores import HIGHSCORES_FILE original_file: Optional[str] = HIGHSCORES_FILE import game.highscores as highscores highscores.HIGHSCORES_FILE = "test_highscores.json" manager: HighScoreManager = HighScoreManager() # Проверяем загрузку данных print(f"[OK] Загружено {len(manager.highscores)} рекордов") # Проверяем метод display_highscores() display_text: str = manager.display_highscores() # Проверяем что в тексте есть заголовок if "ТОП-10 РЕЗУЛЬТАТОВ:" in display_text: print("[OK] Заголовок таблицы рекордов присутствует") else: print("[ERROR] Заголовок таблицы рекордов отсутствует") return False # Проверяем что отображаются все 10 записей lines: List[str] = display_text.split("\n") score_lines: List[str] = [] for line in lines: line = line.strip() if line and ( line.startswith("1.") or line.startswith("2.") or line.startswith("3.") or line.startswith("4.") or line.startswith("5.") or line.startswith("6.") or line.startswith("7.") or line.startswith("8.") or line.startswith("9.") or line.startswith("10.") ): score_lines.append(line) if len(score_lines) == 10: print(f"[OK] Отображается {len(score_lines)} записей (правильно)") else: print(f"[ERROR] Отображается {len(score_lines)} записей (ожидалось 10)") return False # Проверяем что записи отсортированы правильно (по убыванию очков) scores_in_text: List[int] = [] for line in score_lines: # Извлекаем число из строки вида "1. TestPlayer1 - 50 очков" parts: List[str] = line.split("-") if len(parts) >= 2: score_part: str = parts[1].strip() score_num: int = int(score_part.split()[0]) scores_in_text.append(score_num) if scores_in_text == sorted(scores_in_text, reverse=True): print("[OK] Записи отсортированы по убыванию очков") else: print("[ERROR] Записи неправильно отсортированы") print(f"Полученный порядок: {scores_in_text}") return False # Проверяем get_top_scores() top_scores: List[Dict[str, Any]] = manager.get_top_scores() if len(top_scores) == 10: print("[OK] get_top_scores() возвращает 10 записей") else: print(f"[ERROR] get_top_scores() возвращает {len(top_scores)} записей") return False # Проверяем is_top_score() # При полной таблице рекордов (10 записей) результат с 0 очками не должен попадать в топ is_top: bool = manager.is_top_score(0) if not is_top: print("[OK] is_top_score(0) возвращает False для полной таблицы") else: print("[ERROR] is_top_score(0) должен возвращать False для полной таблицы") return False # При полной таблице рекордов результат с 6 очками должен попадать в топ is_top = manager.is_top_score(6) if is_top: print("[OK] is_top_score(6) возвращает True для полной таблицы") else: print("[ERROR] is_top_score(6) должен возвращать True для полной таблицы") return False print("\n[SUCCESS] Все тесты логики отображения пройдены!") return True finally: # Восстанавливаем оригинальный файл if original_file is not None: import game.highscores as highscores highscores.HIGHSCORES_FILE = original_file # Удаляем тестовый файл if os.path.exists("test_highscores.json"): os.unlink("test_highscores.json") def test_score_limits() -> bool: """Тестирует ограничения на 10 записей""" print("\n" + "=" * 60) print("ТЕСТ ОГРАНИЧЕНИЙ НА 10 ЗАПИСЕЙ") print("=" * 60) from game.highscores import HIGHSCORES_FILE original_file: Optional[str] = HIGHSCORES_FILE import game.highscores as highscores highscores.HIGHSCORES_FILE = "test_limits.json" try: manager: HighScoreManager = HighScoreManager() # Добавляем 12 результатов added_count: int = 0 for i in range(12): player_name: str = f"TestPlayer{i+1}" score: int = 50 - i # Убывающие очки: 50, 49, 48, ..., 39 saved: bool = manager.add_score(player_name, score, 60 + i) if saved: added_count += 1 print(f"[OK] {player_name} ({score} очков) - сохранен") else: print(f"[NO] {player_name} ({score} очков) - отклонен") # Проверяем что сохранилось ровно 10 записей if len(manager.highscores) == 10: print(f"[OK] Сохранено ровно 10 записей (из {added_count} допущенных)") else: print(f"[ERROR] Сохранено {len(manager.highscores)} записей (ожидалось 10)") return False # Проверяем что это действительно топ-10 scores: List[int] = [score["score"] for score in manager.highscores] expected_scores: List[int] = list( range(50, 40, -1) ) # 50, 49, 48, ..., 41 (только первые 10) if scores == expected_scores: print("[OK] Сохранены именно топ-10 результатов") else: print( f"[ERROR] Неправильные результаты. Получено: {scores}, ожидалось: {expected_scores}" ) return False print("\n[SUCCESS] Все тесты ограничений пройдены!") return True finally: if original_file is not None: import game.highscores as highscores highscores.HIGHSCORES_FILE = original_file if os.path.exists("test_limits.json"): os.unlink("test_limits.json") def test_interface_flow_simulation() -> bool: """Симулирует пользовательский интерфейс без pygame""" print("\n" + "=" * 60) print("ТЕСТ СИМУЛЯЦИИ ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА") print("=" * 60) # Симулируем сценарий использования: # 1. Игрок заходит в игру # 2. Нажимает H для просмотра таблицы рекордов на стартовом экране # 3. Возвращается к вводу имени # 4. Играет и получает результат # 5. Снова просматривает таблицу с ESC для выхода из игры print("Сценарий 1: Просмотр таблицы на стартовом экране") print("- Пользователь нажимает H на экране ввода имени") print("- Должна открыться таблица рекордов") print("- ESC и Backspace должны возвращать к вводу имени") print("- Крестик окна должен закрывать игру") print("-> Логика реализована в get_player_name()") print("\nСценарий 2: Просмотр таблицы после игры") print("- Пользователь нажимает H на экране результатов") print("- Должна открыться таблица рекордов") print("- ESC должен выходить из игры полностью") print("- Backspace должен возвращать к экрану результатов") print("- Крестик окна должен закрывать игру") print("-> Логика реализована в show_game_results()") print("\nСценарий 3: Навигация") print("- ESC из любого места игры закрывает игру") print("- Backspace возвращает на один шаг назад") print("- Крестик окна всегда закрывает игру") print("-> Логика реализована во всех функциях") # Проверяем что у нас есть все необходимые функции from game.PyGameBall import get_player_name, show_highscores, show_game_results print("\n[OK] Все функции интерфейса доступны") print( "[OK] Сигнатура show_highscores(): (screen, font, highscore_manager, exit_on_esc=False)" ) print( "[OK] Сигнатура get_player_name(): (screen, font, big_font, highscore_manager)" ) print( "[OK] Сигнатура show_game_results(): (screen, font, big_font, score, player_name, time, manager)" ) print("\n[SUCCESS] Симуляция интерфейса корректна!") return True def main() -> bool: """Запуск всех тестов""" print("ТЕСТИРОВАНИЕ УЛУЧШЕНИЙ ИНТЕРФЕЙСА ИГРЫ") print("=" * 60) test1: bool = test_highscores_display_logic() test2: bool = test_score_limits() test3: bool = test_interface_flow_simulation() print("\n" + "=" * 60) print("ИТОГОВЫЕ РЕЗУЛЬТАТЫ") print("=" * 60) if test1 and test2 and test3: print("[SUCCESS] ВСЕ ТЕСТЫ ПРОЙДЕНЫ УСПЕШНО!") print("\nРеализованные улучшения:") print("1. [OK] Выход из игры по ESC из любого места") print("2. [OK] Выход из игры по крестику на окне") print("3. [OK] Просмотр таблицы рекордов на стартовом экране (кнопка H)") print("4. [OK] Возврат к вводу имени после просмотра таблицы") print("5. [OK] Разное поведение ESC в зависимости от контекста") print("6. [OK] Сохранение состояния ввода при переходах") return True else: print("[FAILED] НЕКОТОРЫЕ ТЕСТЫ НЕ ПРОЙДЕНЫ!") return False if __name__ == "__main__": success = main() sys.exit(0 if success else 1)