#!/usr/bin/env python3 """ CLI pour Replay Simulation Report - Fiche #16 Script de ligne de commande pour exécuter des tests headless des règles de résolution de cibles sans interaction UI. Usage: python replay_simulation_cli.py --dataset "form_*" --max-cases 50 python replay_simulation_cli.py --dataset "**" --out-json results.json --out-md report.md Auteur : Dom, Alice Kiro - 22 décembre 2025 """ import argparse import logging import sys from pathlib import Path # Ajouter le répertoire racine au path pour les imports sys.path.insert(0, str(Path(__file__).parent)) from core.evaluation.replay_simulation import ReplaySimulation def setup_logging(verbose: bool = False) -> None: """Configurer le logging selon le niveau de verbosité""" level = logging.DEBUG if verbose else logging.INFO format_str = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' logging.basicConfig( level=level, format=format_str, handlers=[ logging.StreamHandler(sys.stdout) ] ) # Réduire le bruit des librairies externes if not verbose: logging.getLogger('urllib3').setLevel(logging.WARNING) logging.getLogger('requests').setLevel(logging.WARNING) def main(): """Fonction principale du CLI""" parser = argparse.ArgumentParser( description="Replay Simulation Report - Test headless des règles de résolution" ) parser.add_argument( "--dataset", type=str, default="**", help="Pattern de dataset à charger (ex: 'form_*', '**')" ) parser.add_argument( "--max-cases", type=int, help="Nombre maximum de cas à traiter" ) parser.add_argument( "--out-json", type=str, default="replay_report.json", help="Fichier de sortie JSON" ) parser.add_argument( "--out-md", type=str, default="replay_report.md", help="Fichier de sortie Markdown" ) parser.add_argument( "--dataset-root", type=str, default="tests/dataset", help="Racine des datasets de test" ) parser.add_argument( "--verbose", action="store_true", help="Mode verbose" ) args = parser.parse_args() # Configuration du logging level = logging.DEBUG if args.verbose else logging.INFO logging.basicConfig(level=level, format='%(asctime)s - %(levelname)s - %(message)s') # Créer le simulateur simulator = ReplaySimulation(dataset_root=Path(args.dataset_root)) # Charger les cas de test print(f"Chargement des cas de test depuis {args.dataset_root} (pattern: {args.dataset})") test_cases = simulator.load_test_cases(args.dataset, args.max_cases) if not test_cases: print("❌ Aucun cas de test trouvé") return 1 print(f"✅ {len(test_cases)} cas de test chargés") # Exécuter la simulation print("🚀 Démarrage de la simulation...") report = simulator.run_simulation(test_cases) # Exporter les rapports json_path = Path(args.out_json) md_path = Path(args.out_md) simulator.export_json_report(report, json_path) simulator.export_markdown_report(report, md_path) # Afficher le résumé print("\n" + "="*60) print("📊 RÉSUMÉ DE SIMULATION") print("="*60) print(f"Cas traités : {report.total_cases}") print(f"Succès : {report.successful_cases} ({report.success_rate:.1%})") print(f"Précision : {report.correct_cases} ({report.accuracy_rate:.1%})") print(f"Risque moyen : {report.average_risk:.3f}") print(f"Temps total : {report.performance_stats['total_simulation_time_ms']:.1f}ms") print(f"Débit : {report.performance_stats['cases_per_second']:.1f} cas/sec") print("\n📄 Rapports générés :") print(f" - JSON : {json_path}") print(f" - Markdown : {md_path}") return 0 if __name__ == "__main__": exit(main())