mirror of
https://github.com/FerraSoft/bottohelp.git
synced 2026-08-06 21:55:03 +00:00
Подготовка к релизу
This commit is contained in:
+282
@@ -0,0 +1,282 @@
|
||||
# -*- 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())
|
||||
Reference in New Issue
Block a user