Files
bottohelp/run_tests.py
T

282 lines
10 KiB
Python

# -*- coding: utf-8 -*-
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
#!/usr/bin/env python3
"""
Скрипт для запуска полного тестирования телеграм-бота.
Выполняет все типы тестов и генерирует отчеты.
"""
import subprocess
import sys
import os
import argparse
from datetime import datetime
import json
# Добавляем корневую директорию в путь
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
def run_command(cmd: str, description: str) -> bool:
"""
Запуск команды с логированием.
Args:
cmd: Команда для выполнения
description: Описание команды
Returns:
True если команда выполнена успешно
"""
print(f"\n🔄 {description}")
print(f"Выполняется: {cmd}")
try:
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
if result.returncode == 0:
print(f"✅ {description} - УСПЕХ")
if result.stdout:
print(f"Вывод: {result.stdout.strip()}")
return True
else:
print(f"❌ {description} - ОШИБКА")
print(f"Код ошибки: {result.returncode}")
if result.stderr:
print(f"Ошибка: {result.stderr.strip()}")
return False
except Exception as e:
print(f"❌ {description} - ИСКЛЮЧЕНИЕ: {e}")
return False
def install_test_dependencies():
"""Установка зависимостей для тестирования"""
print("\n📦 Установка зависимостей для тестирования...")
# Проверяем, установлен ли pytest
try:
import pytest
print("✅ pytest уже установлен")
except ImportError:
print("📥 Установка pytest...")
if not run_command("pip install pytest pytest-asyncio pytest-mock", "Установка основных зависимостей pytest"):
print("❌ Не удалось установить зависимости pytest")
return False
# Устанавливаем зависимости из файла
if os.path.exists("requirements-test.txt"):
if not run_command("pip install -r requirements-test.txt", "Установка тестовых зависимостей"):
print("⚠️ Некоторые тестовые зависимости не удалось установить")
else:
print("⚠️ Файл requirements-test.txt не найден")
return True
def run_unit_tests():
"""Запуск unit тестов"""
return run_command(
"python -m pytest tests/ -v --tb=short -m unit",
"Запуск unit тестов"
)
def run_integration_tests():
"""Запуск интеграционных тестов"""
return run_command(
"python -m pytest test_integration/ -v --tb=short",
"Запуск интеграционных тестов"
)
def run_all_tests():
"""Запуск всех тестов"""
return run_command(
"python -m pytest tests/ test_utils/ test_services/ test_handlers/ test_integration/ -v --tb=short",
"Запуск всех тестов"
)
def run_coverage_report():
"""Генерация отчета о покрытии кода"""
success = run_command(
"python -m pytest --cov=telegram_bot --cov-report=html --cov-report=term-missing tests/ test_utils/ test_services/ test_handlers/ test_integration/",
"Генерация отчета покрытия"
)
if success:
print("📊 Отчет покрытия сохранен в htmlcov/index.html")
print("📈 Краткий отчет покрытия выведен выше")
return success
def run_performance_tests():
"""Запуск тестов производительности"""
return run_command(
"python -m pytest -v --tb=short -k performance",
"Запуск тестов производительности"
)
def lint_code():
"""Проверка кода линтером"""
print("\n🔍 Проверка качества кода...")
# Проверяем, установлен ли flake8
try:
import flake8
except ImportError:
print("📥 Установка flake8...")
if not run_command("pip install flake8", "Установка flake8"):
print("⚠️ Пропускаем проверку линтером")
return True
# Запускаем flake8
return run_command(
"python -m flake8 telegram_bot/ --count --select=E9,F63,F7,F82 --show-source --statistics",
"Проверка кода flake8 (критические ошибки)"
)
def check_imports():
"""Проверка корректности импортов"""
print("\n🔗 Проверка импортов...")
# Проверяем основные модули новой архитектуры
modules_to_check = [
"core.config",
"core.exceptions",
"utils.validators",
"utils.formatters",
"utils.helpers",
"services.user_service",
"handlers.base_handler",
"handlers.user_handlers",
"database.models",
"database.repository"
]
all_success = True
for module in modules_to_check:
try:
__import__(module)
print(f"✅ {module}")
except Exception as e:
print(f"❌ {module}: {e}")
all_success = False
return all_success
def analyze_test_results():
"""Анализ результатов тестирования"""
print("\n📊 Анализ результатов тестирования...")
try:
# Читаем результаты последних тестов
result_file = "test_results.json"
if os.path.exists(result_file):
with open(result_file, 'r', encoding='utf-8') as f:
results = json.load(f)
print("📈 Статистика тестирования:")
print(f" Всего тестов: {results.get('total', 0)}")
print(f" Пройдено: {results.get('passed', 0)}")
print(f" Провалено: {results.get('failed', 0)}")
print(f" Пропущено: {results.get('skipped', 0)}")
print(f" Время выполнения: {results.get('duration', 0):.2f} сек")
success_rate = (results.get('passed', 0) / results.get('total', 1)) * 100
print(f" Успешность: {success_rate:.1f}%")
if success_rate >= 90:
print("🎉 Отличные результаты тестирования!")
elif success_rate >= 70:
print("👍 Хорошие результаты, но есть над чем поработать")
else:
print("⚠️ Требуется улучшение качества кода и тестов")
else:
print("📋 Результаты тестирования не найдены")
except Exception as e:
print(f"⚠️ Не удалось проанализировать результаты: {e}")
def main():
"""Главная функция"""
parser = argparse.ArgumentParser(description="Запуск тестирования телеграм-бота")
parser.add_argument("--unit", action="store_true", help="Запустить только unit тесты")
parser.add_argument("--integration", action="store_true", help="Запустить только интеграционные тесты")
parser.add_argument("--coverage", action="store_true", help="Генерировать отчет покрытия")
parser.add_argument("--performance", action="store_true", help="Запустить тесты производительности")
parser.add_argument("--lint", action="store_true", help="Проверить код линтером")
parser.add_argument("--quick", action="store_true", help="Быстрое тестирование (только критические тесты)")
args = parser.parse_args()
print("🧪 Начинаем тестирование телеграм-бота")
print(f"🕐 Время начала: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
# Установка зависимостей
if not install_test_dependencies():
print("❌ Не удалось установить зависимости")
return 1
# Проверка импортов
if not check_imports():
print("❌ Проблемы с импортами модулей")
return 1
# Проверка линтера
if args.lint:
if not lint_code():
print("❌ Найдены проблемы с качеством кода")
return 1
# Запуск тестов
test_success = False
if args.unit:
test_success = run_unit_tests()
elif args.integration:
test_success = run_integration_tests()
elif args.performance:
test_success = run_performance_tests()
elif args.quick:
# Быстрое тестирование - только основные компоненты
test_success = run_command(
"python -m pytest test_utils/ test_services/ -v --tb=short",
"Быстрое тестирование"
)
else:
# Полное тестирование
test_success = run_all_tests()
# Генерация отчета покрытия
if args.coverage and test_success:
run_coverage_report()
# Анализ результатов
analyze_test_results()
# Итоговый результат
print(f"\n🏁 Тестирование завершено: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
if test_success:
print("✅ Все тесты пройдены успешно!")
return 0
else:
print("❌ Некоторые тесты провалились")
return 1
if __name__ == "__main__":
sys.exit(main())