Files
rpa_vision_v3/tests/unit/test_fiche4_imports_stables.py
Dom cf495dd82f feat: chat unifié, GestureCatalog, Copilot, Léa UI, extraction données, vérification replay
Refonte majeure du système Agent Chat et ajout de nombreux modules :

- Chat unifié : suppression du dual Workflows/Agent Libre, tout passe par /api/chat
  avec résolution en 3 niveaux (workflow → geste → "montre-moi")
- GestureCatalog : 38 raccourcis clavier universels Windows avec matching sémantique,
  substitution automatique dans les replays, et endpoint /api/gestures
- Mode Copilot : exécution pas-à-pas des workflows avec validation humaine via WebSocket
  (approve/skip/abort) avant chaque action
- Léa UI (agent_v0/lea_ui/) : interface PyQt5 pour Windows avec overlay transparent
  pour feedback visuel pendant le replay
- Data Extraction (core/extraction/) : moteur d'extraction visuelle de données
  (OCR + VLM → SQLite), avec schémas YAML et export CSV/Excel
- ReplayVerifier (agent_v0/server_v1/) : vérification post-action par comparaison
  de screenshots, avec logique de retry (max 3)
- IntentParser durci : meilleur fallback regex, type GREETING, patterns améliorés
- Dashboard : nouvelles pages gestures, streaming, extractions
- Tests : 63 tests GestureCatalog, 47 tests extraction, corrections tests existants
- Dépréciation : /api/agent/plan et /api/agent/execute retournent HTTP 410,
  suppression du code hardcodé _plan_to_replay_actions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 10:02:09 +01:00

147 lines
5.6 KiB
Python

"""
Tests pour Fiche #4 - Imports & Tests Stables
Auteur: Dom, Alice Kiro - 15 décembre 2024
Objectif: Valider que les imports sont stables et reproductibles
"""
import pytest
import sys
import importlib
from pathlib import Path
@pytest.mark.fiche4
class TestFiche4ImportsStables:
"""Tests pour la Fiche #4 - Imports stables"""
def test_core_module_accessible(self):
"""Test que le module core est accessible"""
try:
import core
assert core is not None
print(f"✅ Core accessible depuis: {core.__file__}")
except ImportError as e:
pytest.fail(f"Module core non accessible: {e}")
def test_core_models_import(self):
"""Test import des modèles core"""
try:
from core.models import ScreenState, UIElement, TargetSpec
assert ScreenState is not None
assert UIElement is not None
assert TargetSpec is not None
except ImportError as e:
pytest.fail(f"Import core.models échoué: {e}")
def test_core_execution_import(self):
"""Test import des modules d'exécution"""
try:
from core.execution import TargetResolver, ActionExecutor
assert TargetResolver is not None
assert ActionExecutor is not None
except ImportError as e:
pytest.fail(f"Import core.execution échoué: {e}")
def test_core_detection_import(self):
"""Test import des modules de détection"""
try:
from core.detection import UIDetector
assert UIDetector is not None
except ImportError as e:
pytest.fail(f"Import core.detection échoué: {e}")
def test_no_rpa_vision_v3_imports_in_tests(self):
"""Test qu'aucun test n'utilise rpa_vision_v3.core"""
tests_dir = Path(__file__).parent
bad_imports = []
for test_file in tests_dir.glob("test_*.py"):
if test_file.name == "test_fiche4_imports_stables.py":
continue
try:
with open(test_file, 'r') as f:
content = f.read()
# Chercher les imports NON-CONFORMES (rpa_vision_v3.core)
if 'from rpa_vision_v3.core' in content or 'import rpa_vision_v3.core' in content:
bad_imports.append(test_file.name)
except Exception:
pass
if bad_imports:
pytest.fail(f"Fichiers avec imports non-conformes: {bad_imports}")
def test_pytest_runs_from_root(self):
"""Test que pytest fonctionne depuis la racine"""
# Vérifier qu'on est dans le bon environnement
cwd = Path.cwd()
assert (cwd / "core").exists(), "Dossier 'core' non trouvé - pytest doit être lancé depuis la racine"
assert (cwd / "tests").exists(), "Dossier 'tests' non trouvé"
assert (cwd / "pytest.ini").exists(), "pytest.ini non trouvé"
def test_conftest_loaded(self):
"""Test que conftest.py est bien chargé"""
# Vérifier que le chemin racine est dans sys.path
root_path = str(Path(__file__).resolve().parents[2])
assert root_path in sys.path, f"Chemin racine {root_path} non dans sys.path - conftest.py non chargé?"
def test_import_consistency(self):
"""Test cohérence des imports entre différents modules"""
# Importer le même module de différentes façons
try:
from core.models.ui_element import UIElement as UIElement1
from core.models import UIElement as UIElement2
# Doivent être le même objet
assert UIElement1 is UIElement2, "Imports incohérents pour UIElement"
except ImportError as e:
pytest.fail(f"Import incohérent: {e}")
def test_no_circular_imports(self):
"""Test absence d'imports circulaires"""
# Tenter d'importer tous les modules principaux
modules_to_test = [
'core.models',
'core.execution',
'core.detection',
'core.embedding',
'core.graph'
]
for module_name in modules_to_test:
try:
importlib.import_module(module_name)
except ImportError as e:
if "circular import" in str(e).lower():
pytest.fail(f"Import circulaire détecté dans {module_name}: {e}")
# Autres erreurs d'import peuvent être OK (dépendances manquantes)
@pytest.mark.performance
def test_import_speed(self):
"""Test que les imports sont rapides"""
import time
start = time.time()
from core.models import ScreenState, UIElement
from core.execution import TargetResolver
end = time.time()
import_time = end - start
assert import_time < 1.0, f"Imports trop lents: {import_time:.2f}s"
@pytest.mark.skip(reason="Script validate_imports.py supprimé lors du nettoyage")
def test_validate_imports_script_works(self):
"""Test que le script validate_imports.py fonctionne"""
validate_script = Path(__file__).parents[2] / "validate_imports.py"
assert validate_script.exists(), "Script validate_imports.py non trouvé"
# Tenter d'importer le module
try:
import validate_imports
assert hasattr(validate_imports, 'ImportValidator')
except ImportError as e:
pytest.fail(f"Script validate_imports.py non importable: {e}")
if __name__ == "__main__":
pytest.main([__file__, "-v"])