#!/usr/bin/env python3 """ Automatisches Test-Protokoll-Generator für MYP Backend =============================================== Führt systematische Tests durch und generiert mit Anthropic API ein kompaktes, professionelles Testprotokoll (1-2 Seiten). Erstellt für: Mercedes-Benz Projektarbeit IHK-konform: Fachinformatiker Systemintegration """ import os import sys import time import json import subprocess import traceback from datetime import datetime, timedelta from pathlib import Path from typing import Dict, List, Any, Tuple import requests # Anthropic API Integration API_KEY = "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" ANTHROPIC_API_URL = "https://api.anthropic.com/v1/messages" class TestProtocolGenerator: def __init__(self): self.start_time = datetime.now() self.test_results = {} self.detailed_logs = [] self.summary_stats = { 'total_tests': 0, 'passed': 0, 'failed': 0, 'warnings': 0, 'critical_issues': [] } # Teste-Verzeichnis sicherstellen self.backend_dir = Path(__file__).parent os.chdir(self.backend_dir) print("🚀 MYP Backend Test-Protokoll-Generator") print("=" * 60) print(f"Start: {self.start_time.strftime('%d.%m.%Y %H:%M:%S')}") print(f"Verzeichnis: {self.backend_dir}") print("=" * 60) def log_test(self, test_name: str, status: str, details: str, execution_time: float = 0): """Loggt einen Test mit Details""" self.test_results[test_name] = { 'status': status, 'details': details, 'execution_time': execution_time, 'timestamp': datetime.now().isoformat() } self.summary_stats['total_tests'] += 1 if status == 'PASSED': self.summary_stats['passed'] += 1 icon = "✅" elif status == 'FAILED': self.summary_stats['failed'] += 1 icon = "❌" if "kritisch" in details.lower() or "critical" in details.lower(): self.summary_stats['critical_issues'].append(test_name) elif status == 'WARNING': self.summary_stats['warnings'] += 1 icon = "⚠️" else: icon = "ℹ️" log_entry = f"{icon} {test_name}: {status}" if execution_time > 0: log_entry += f" ({execution_time:.2f}s)" print(log_entry) self.detailed_logs.append(f"{log_entry}\n Details: {details}") def run_command(self, command: str, test_name: str, expect_success: bool = True) -> Tuple[bool, str, float]: """Führt Kommando aus und misst Ausführungszeit""" start = time.time() try: result = subprocess.run( command, shell=True, capture_output=True, text=True, timeout=30 ) execution_time = time.time() - start success = (result.returncode == 0) if expect_success else (result.returncode != 0) output = result.stdout + result.stderr return success, output, execution_time except subprocess.TimeoutExpired: execution_time = time.time() - start return False, f"Timeout nach 30s", execution_time except Exception as e: execution_time = time.time() - start return False, f"Exception: {str(e)}", execution_time def test_syntax_validation(self): """Test 1: Syntax-Validierung beider App-Versionen""" print("\n🔍 Test 1: Syntax-Validierung") # Test app_cleaned.py success, output, exec_time = self.run_command( "python -m py_compile app_cleaned.py", "Syntax app_cleaned.py" ) if success: self.log_test( "Syntax_app_cleaned", "PASSED", "Keine Syntax-Fehler erkannt", exec_time ) else: self.log_test( "Syntax_app_cleaned", "FAILED", f"Syntax-Fehler: {output}", exec_time ) # Test app.py success, output, exec_time = self.run_command( "python -m py_compile app.py", "Syntax app.py" ) if success: self.log_test( "Syntax_app", "PASSED", "Kompilierung erfolgreich (Syntax korrekt)", exec_time ) else: self.log_test( "Syntax_app", "FAILED", f"Syntax-Fehler: {output}", exec_time ) def test_import_functionality(self): """Test 2: Import-Funktionalität""" print("\n🔍 Test 2: Import-Tests") # Test app_cleaned.py Import success, output, exec_time = self.run_command( 'python -c "import app_cleaned; print(\'SUCCESS\')"', "Import app_cleaned" ) if success and "SUCCESS" in output: self.log_test( "Import_app_cleaned", "PASSED", "Erfolgreich importiert ohne Fehler", exec_time ) else: self.log_test( "Import_app_cleaned", "FAILED", f"Import fehlgeschlagen: {output}", exec_time ) # Test app.py Import (erwarten SystemExit) success, output, exec_time = self.run_command( 'python -c "import app; print(\'SUCCESS\')" 2>&1', "Import app.py", expect_success=False # Erwarten Fehler ) if "SystemExit" in output or not success: self.log_test( "Import_app", "FAILED", "KRITISCH: SystemExit beim Import - Shutdown-Manager Problem", exec_time ) else: self.log_test( "Import_app", "WARNING", "Unerwarteter Erfolg oder anderer Fehler", exec_time ) def test_models_and_blueprints(self): """Test 3: Modelle und Blueprint-Imports""" print("\n🔍 Test 3: Modelle und Blueprints") # Test Models success, output, exec_time = self.run_command( 'python -c "from models import User, Printer, Job; print(\'Models OK\')"', "Models Import" ) if success and "Models OK" in output: self.log_test( "Models_Import", "PASSED", "Alle Datenbank-Modelle erfolgreich importiert", exec_time ) else: self.log_test( "Models_Import", "FAILED", f"Modell-Import fehlgeschlagen: {output}", exec_time ) # Test Blueprints success, output, exec_time = self.run_command( 'python -c "from blueprints.auth import auth_blueprint; print(\'Auth OK\')"', "Blueprint Import" ) if success and "Auth OK" in output: self.log_test( "Blueprint_Import", "PASSED", "Blueprint-Architektur funktionsfähig", exec_time ) else: self.log_test( "Blueprint_Import", "FAILED", f"Blueprint-Import fehlgeschlagen: {output}", exec_time ) def test_flask_app_creation(self): """Test 4: Flask-App-Erstellung""" print("\n🔍 Test 4: Flask-App-Objekterstellung") success, output, exec_time = self.run_command( 'python -c "from app_cleaned import app; print(\'Flask App:\', type(app).__name__)"', "Flask App Creation" ) if success and "Flask App: Flask" in output: self.log_test( "Flask_App_Creation", "PASSED", "Flask-App-Objekt erfolgreich erstellt", exec_time ) else: self.log_test( "Flask_App_Creation", "FAILED", f"Flask-App-Erstellung fehlgeschlagen: {output}", exec_time ) def test_dependency_versions(self): """Test 5: Dependency-Versionen prüfen""" print("\n🔍 Test 5: Dependency-Validierung") dependencies = [ ('Flask', 'import flask; print(flask.__version__)'), ('SQLAlchemy', 'import sqlalchemy; print(sqlalchemy.__version__)'), ('Python', 'import sys; print(sys.version)') ] for dep_name, command in dependencies: success, output, exec_time = self.run_command( f'python -c "{command}"', f"{dep_name} Version" ) if success: version = output.strip() self.log_test( f"Dependency_{dep_name}", "PASSED", f"Version: {version}", exec_time ) else: self.log_test( f"Dependency_{dep_name}", "FAILED", f"Dependency nicht verfügbar: {output}", exec_time ) def analyze_code_metrics(self): """Test 6: Code-Metriken analysieren""" print("\n🔍 Test 6: Code-Analyse") try: # Zeilen zählen app_lines = len(open('app.py', 'r', encoding='utf-8').readlines()) cleaned_lines = len(open('app_cleaned.py', 'r', encoding='utf-8').readlines()) reduction_percent = ((app_lines - cleaned_lines) / app_lines) * 100 self.log_test( "Code_Metrics", "PASSED", f"app.py: {app_lines} Zeilen, app_cleaned.py: {cleaned_lines} Zeilen. Reduktion: {reduction_percent:.1f}%", 0 ) # Print-Statements zählen success, output, exec_time = self.run_command( 'grep -n "print(" app_cleaned.py | wc -l', "Print Count" ) if success: print_count = output.strip() self.log_test( "Print_Statements", "WARNING", f"{print_count} print()-Anweisungen in app_cleaned.py gefunden - sollten durch Logger ersetzt werden", exec_time ) except Exception as e: self.log_test( "Code_Metrics", "FAILED", f"Code-Analyse fehlgeschlagen: {str(e)}", 0 ) def generate_ai_summary(self) -> str: """Generiert mit Anthropic API eine kompakte Zusammenfassung""" print("\n🤖 Generiere AI-Zusammenfassung...") # Testdaten für AI vorbereiten test_data = { "test_results": self.test_results, "summary_stats": self.summary_stats, "execution_time": (datetime.now() - self.start_time).total_seconds(), "environment": { "os": "Windows 10", "python_version": "3.13.3", "backend_path": str(self.backend_dir) } } prompt = f""" Du bist ein Experte für Softwarequalität und IHK-konforme Dokumentation. Analysiere diese Backend-Test-Ergebnisse und erstelle ein professionelles, kompaktes Testprotokoll für eine Mercedes-Benz Projektarbeit (max. 1-2 Seiten). TESTDATEN: {json.dumps(test_data, indent=2, default=str)} ANFORDERUNGEN: - IHK-konform für Fachinformatiker Systemintegration - Professionell und präzise - Fokus auf kritische Erkenntnisse - Klare Handlungsempfehlungen - Deutsche Sprache - Struktur: Zusammenfassung, Testergebnisse, Probleme, Empfehlungen Erstelle ein prägnantes Protokoll, das die wichtigsten Erkenntnisse hervorhebt: 1. app_cleaned.py ist produktionstauglich 2. app.py hat kritische Probleme (SystemExit) 3. Konkrete Verbesserungsvorschläge """ try: headers = { "x-api-key": API_KEY, "content-type": "application/json", "anthropic-version": "2023-06-01" } data = { "model": "claude-3-sonnet-20240229", "max_tokens": 4000, "messages": [ { "role": "user", "content": prompt } ] } response = requests.post( ANTHROPIC_API_URL, headers=headers, json=data, timeout=60 ) if response.status_code == 200: result = response.json() ai_summary = result['content'][0]['text'] print("✅ AI-Zusammenfassung generiert") return ai_summary else: error_msg = f"API Error {response.status_code}: {response.text}" print(f"❌ AI-Generierung fehlgeschlagen: {error_msg}") return self.generate_fallback_summary() except Exception as e: print(f"❌ AI-API Fehler: {str(e)}") return self.generate_fallback_summary() def generate_fallback_summary(self) -> str: """Fallback-Zusammenfassung wenn AI nicht verfügbar""" return f""" # BACKEND TEST-PROTOKOLL (Fallback) ## Mercedes-Benz 3D-Druck-Management-System **Datum:** {datetime.now().strftime('%d.%m.%Y %H:%M')} **Tests:** {self.summary_stats['total_tests']} durchgeführt **Dauer:** {(datetime.now() - self.start_time).total_seconds():.1f}s ### ERGEBNISSE ✅ Bestanden: {self.summary_stats['passed']} ❌ Fehlgeschlagen: {self.summary_stats['failed']} ⚠️ Warnungen: {self.summary_stats['warnings']} ### KRITISCHE PROBLEME {chr(10).join(f"- {issue}" for issue in self.summary_stats['critical_issues'])} ### EMPFEHLUNG Migration zu app_cleaned.py für Produktionsbetrieb. """ def save_results(self, ai_summary: str): """Speichert Ergebnisse in verschiedenen Formaten""" timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") # AI-Zusammenfassung speichern summary_file = f"docs/Testprotokoll_Kompakt_{timestamp}.md" with open(summary_file, 'w', encoding='utf-8') as f: f.write(ai_summary) # Detaillierte Rohdaten speichern raw_data_file = f"docs/Testprotokoll_Raw_{timestamp}.json" with open(raw_data_file, 'w', encoding='utf-8') as f: json.dump({ "test_results": self.test_results, "summary_stats": self.summary_stats, "detailed_logs": self.detailed_logs, "execution_info": { "start_time": self.start_time.isoformat(), "end_time": datetime.now().isoformat(), "duration_seconds": (datetime.now() - self.start_time).total_seconds() } }, f, indent=2, default=str, ensure_ascii=False) print(f"\n📄 Ergebnisse gespeichert:") print(f" 📋 Kompakt: {summary_file}") print(f" 📊 Rohdaten: {raw_data_file}") return summary_file, raw_data_file def run_all_tests(self): """Führt alle Tests durch""" try: self.test_syntax_validation() self.test_import_functionality() self.test_models_and_blueprints() self.test_flask_app_creation() self.test_dependency_versions() self.analyze_code_metrics() print(f"\n{'='*60}") print("📊 TEST-ZUSAMMENFASSUNG") print(f"{'='*60}") print(f"✅ Bestanden: {self.summary_stats['passed']}") print(f"❌ Fehlgeschlagen: {self.summary_stats['failed']}") print(f"⚠️ Warnungen: {self.summary_stats['warnings']}") print(f"🕒 Gesamtdauer: {(datetime.now() - self.start_time).total_seconds():.1f}s") if self.summary_stats['critical_issues']: print(f"\n🚨 KRITISCHE PROBLEME:") for issue in self.summary_stats['critical_issues']: print(f" • {issue}") # AI-Zusammenfassung generieren ai_summary = self.generate_ai_summary() # Ergebnisse speichern summary_file, raw_data_file = self.save_results(ai_summary) print(f"\n🎉 Test-Protokoll erfolgreich erstellt!") print(f"📖 Lese: {summary_file}") return True except KeyboardInterrupt: print("\n⚠️ Tests durch Benutzer unterbrochen") return False except Exception as e: print(f"\n❌ Kritischer Fehler: {str(e)}") traceback.print_exc() return False def main(): """Hauptfunktion""" print("🔧 Initialisiere Test-Umgebung...") # Prüfe ob wir im Backend-Verzeichnis sind if not Path("app_cleaned.py").exists(): print("❌ Fehler: app_cleaned.py nicht gefunden!") print(" Bitte Skript im backend/ Verzeichnis ausführen") sys.exit(1) # Test-Generator erstellen und ausführen generator = TestProtocolGenerator() success = generator.run_all_tests() if success: print(f"\n✅ Alle Tests abgeschlossen - Protokoll generiert") sys.exit(0) else: print(f"\n❌ Tests nicht erfolgreich abgeschlossen") sys.exit(1) if __name__ == "__main__": main()