""" Test Registry Data Models Definiert die Datenstrukturen fuer das zentrale Test-Dashboard. """ from dataclasses import dataclass, field from datetime import datetime from enum import Enum from typing import Optional, List, Dict, Any class TestFramework(str, Enum): GO_TEST = "go_test" PYTEST = "pytest" JEST = "jest" PLAYWRIGHT = "playwright" BQAS_GOLDEN = "bqas_golden" BQAS_RAG = "bqas_rag" BQAS_SYNTHETIC = "bqas_synthetic" class TestCategory(str, Enum): UNIT = "unit" INTEGRATION = "integration" E2E = "e2e" BQAS = "bqas" SECURITY = "security" PERFORMANCE = "performance" class TestStatus(str, Enum): PENDING = "pending" RUNNING = "running" PASSED = "passed" FAILED = "failed" SKIPPED = "skipped" ERROR = "error" class RunStatus(str, Enum): QUEUED = "queued" RUNNING = "running" COMPLETED = "completed" FAILED = "failed" CANCELLED = "cancelled" @dataclass class TestCase: """Einzelner Testfall""" id: str name: str file_path: str line_number: Optional[int] = None framework: TestFramework = TestFramework.GO_TEST category: TestCategory = TestCategory.UNIT duration_ms: Optional[float] = None status: TestStatus = TestStatus.PENDING error_message: Optional[str] = None output: Optional[str] = None @dataclass class TestSuite: """Test-Suite eines Services""" id: str service: str name: str framework: TestFramework category: TestCategory base_path: str pattern: str # z.B. "*_test.go" oder "test_*.py" tests: List[TestCase] = field(default_factory=list) total_tests: int = 0 passed_tests: int = 0 failed_tests: int = 0 skipped_tests: int = 0 duration_ms: float = 0.0 coverage_percent: Optional[float] = None last_run: Optional[datetime] = None status: TestStatus = TestStatus.PENDING @dataclass class TestRun: """Ein Test-Durchlauf""" id: str suite_id: str service: str started_at: datetime completed_at: Optional[datetime] = None status: RunStatus = RunStatus.QUEUED total_tests: int = 0 passed_tests: int = 0 failed_tests: int = 0 skipped_tests: int = 0 duration_seconds: float = 0.0 git_commit: Optional[str] = None git_branch: Optional[str] = None coverage_percent: Optional[float] = None triggered_by: str = "manual" output: Optional[str] = None failed_test_ids: List[str] = field(default_factory=list) @dataclass class CoverageReport: """Coverage-Bericht fuer einen Service""" service: str framework: TestFramework line_coverage: float branch_coverage: Optional[float] = None function_coverage: Optional[float] = None statement_coverage: Optional[float] = None uncovered_files: List[str] = field(default_factory=list) timestamp: datetime = field(default_factory=datetime.now) @dataclass class ServiceTestInfo: """Aggregierte Test-Informationen fuer einen Service""" service: str display_name: str port: Optional[int] = None language: str = "unknown" total_tests: int = 0 passed_tests: int = 0 failed_tests: int = 0 skipped_tests: int = 0 pass_rate: float = 0.0 coverage_percent: Optional[float] = None last_run: Optional[datetime] = None status: TestStatus = TestStatus.PENDING suites: List[TestSuite] = field(default_factory=list) @dataclass class TestRegistryStats: """Gesamtstatistik des Test-Registrys""" total_tests: int = 0 total_passed: int = 0 total_failed: int = 0 total_skipped: int = 0 overall_pass_rate: float = 0.0 average_coverage: Optional[float] = None services_count: int = 0 last_full_run: Optional[datetime] = None by_category: Dict[str, int] = field(default_factory=dict) by_framework: Dict[str, int] = field(default_factory=dict) # Service-Definitionen mit Test-Informationen SERVICE_DEFINITIONS = [ { "service": "consent-service", "display_name": "Consent Service", "port": 8081, "language": "go", "base_path": "/consent-service", "test_pattern": "*_test.go", "framework": TestFramework.GO_TEST, }, { "service": "backend", "display_name": "Python Backend", "port": 8000, "language": "python", "base_path": "/backend/tests", "test_pattern": "test_*.py", "framework": TestFramework.PYTEST, }, { "service": "voice-service", "display_name": "Voice Service", "port": 8091, "language": "python", "base_path": "/app/tests", "test_pattern": "test_*.py", "framework": TestFramework.PYTEST, "container_name": "breakpilot-pwa-voice-service", "run_in_container": True, "pytest_args": "--ignore=/app/tests/bqas", # Exclude BQAS tests - run separately }, { "service": "klausur-service", "display_name": "Klausur Service", "port": 8086, "language": "python", "base_path": "/app/tests", "test_pattern": "test_*.py", "framework": TestFramework.PYTEST, "container_name": "breakpilot-pwa-klausur-service", "run_in_container": True, }, { "service": "billing-service", "display_name": "Billing Service", "port": 8082, "language": "go", "base_path": "/billing-service", "test_pattern": "*_test.go", "framework": TestFramework.GO_TEST, }, { "service": "school-service", "display_name": "School Service", "port": 8084, "language": "go", "base_path": "/school-service", "test_pattern": "*_test.go", "framework": TestFramework.GO_TEST, }, { "service": "edu-search-service", "display_name": "Edu Search Service", "port": 8088, "language": "go", "base_path": "/edu-search-service", "test_pattern": "*_test.go", "framework": TestFramework.GO_TEST, }, { "service": "ai-compliance-sdk", "display_name": "AI Compliance SDK", "port": None, "language": "go", "base_path": "/ai-compliance-sdk", "test_pattern": "*_test.go", "framework": TestFramework.GO_TEST, }, { "service": "geo-service", "display_name": "Geo Service", "port": 8089, "language": "mixed", "base_path": "/geo-service", "test_pattern": "*_test.go", "framework": TestFramework.GO_TEST, "disabled": True, # Keine Tests vorhanden - Verzeichnis ist leer "disabled_reason": "Keine Test-Dateien vorhanden", }, { "service": "website", "display_name": "Website (Jest)", "port": 3000, "language": "typescript", "base_path": "/website", "test_pattern": "*.test.{ts,tsx}", "framework": TestFramework.JEST, "requires_setup": True, # Erfordert npm install im Website-Verzeichnis "setup_note": "Fuehren Sie 'npm install' im website-Verzeichnis aus, um Tests lokal auszufuehren", }, # Website E2E entfernt - keine Playwright-Tests vorhanden { "service": "bqas-golden", "display_name": "BQAS Golden Suite", "port": 8091, "language": "python", "base_path": "/app/tests/bqas/test_golden.py", "test_pattern": "test_*.py", "framework": TestFramework.PYTEST, "container_name": "breakpilot-pwa-voice-service", "run_in_container": True, }, { "service": "bqas-rag", "display_name": "BQAS RAG Tests", "port": 8091, "language": "python", "base_path": "/app/tests/bqas/test_rag.py", "test_pattern": "test_*.py", "framework": TestFramework.PYTEST, "container_name": "breakpilot-pwa-voice-service", "run_in_container": True, }, ]