veza/docs/STRATEGIE_COUVERTURE_ET_TMT_2025_02.md
senke 8a0f008345 chore: playwright workflow, docs, rapports audit, visual-tests, tmt unit
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 22:19:34 +01:00

13 KiB
Raw Permalink Blame History

STRATÉGIE DE COUVERTURE & ORCHESTRATION TMT — VEZA

Date : 2025-02-10
Mandat : Architecte qualité — redressement de la base de tests
Audits de référence : AUDIT_TESTS_ET_COUVERTURE_2025_02.md, AUDIT_FRONTEND_EXHAUSTIF_2025_02.md
Objectif : « Une régression significative ne peut plus passer inaperçue. »


0. POSTURE

Décisions appliquées. Pas de pédagogie. Pas de généralités.


1. REDÉFINITION DE LA COUVERTURE

1.1 Définition opérationnelle

Couverture = probabilité que le système se comporte correctement lorsqu'il est modifié.

Trois axes :

Axe Signification Mesure
Logique critique Auth, RBAC, commerce, upload, webhooks Branches exercées sur chemins nominaux ET erreurs
Branches d'erreur catch, retry, fallback, validation % branches catch/error couvertes
Contrats implicites API, auth, invariants métier Tests contractuels, assertions sur schémas

1.2 Cibles chiffrées (différenciées)

Domaine Cible branches Cible lignes Bloquant
Auth / RBAC ≥ 90% ≥ 85% Oui
Commerce / Marketplace ≥ 85% ≥ 80% Oui
Upload / Tracks ≥ 85% ≥ 80% Oui
Services API (client.ts, interceptors) ≥ 80% ≥ 75% Oui
Handlers / Services Go critiques ≥ 90% ≥ 85% Oui
Hooks / utils frontend ≥ 80% ≥ 80% Oui
Logique utilitaire ≥ 80% ≥ 80% Non (warning)
UI pure (composants) Indicateur Indicateur Non

Pourquoi un seuil global unique est architecturalement débile :
Un seuil global (ex. 80%) masque les zones critiques sous-testées. Le client API (2238 lignes) peut être négligé tandis que des utils triviales gonflent le pourcentage. Les domaines à fort risque (auth, RBAC) doivent avoir des seuils plus élevés et être vérifiés séparément.


2. STRATÉGIE PAR COUCHE

2.1 Backend (Go)

Fonctions critiques identifiées (à couvrir en priorité) :

  • internal/core/auth/service.go — ValidateSession, HasRole, HasPermission
  • internal/api/router.go — Middleware auth, RBAC
  • Handlers : auth, tracks, playlists, marketplace, webhooks
  • internal/database/ — Migrations, prepared statements (chemins erreur)

Tests à écrire/corriger :

Type Action Justification
Chemins nominaux Corriger mocks auth middleware Échec actuel : 0 out of 1 expectation(s) were met
Erreurs métier Ajouter tests sur erreurs 401, 403, 404 RBAC non validé
Erreurs infra Simuler DB down, timeout Branches jamais exercées

Interdictions :

  • Mocks non alignés avec les interfaces réelles (signatures Go)
  • Tests dépendants du timing (supprimer ou utiliser testify/assert.Eventually)

2.2 Frontend

Couche Rôle Outil Couverture
Unitaire Hooks, helpers, utils, services purs Vitest branches ≥ 80% sur features/*, hooks, services
Intégration Pages, flows (MSW) Vitest + MSW Pas de logique métier significative non testée hors E2E
E2E Flux critiques (auth, playlists, search) Playwright Smoke obligatoire

Objectif : Zéro logique métier significative non testée hors E2E.

Zones prioritaires :

  • authStore vs AuthContext — cohérence (réduire après unification auth)
  • client.ts — découper puis tester interceptors, retry, offline queue
  • optimisticUpdates.ts — rollback, invalidation
  • marketplaceService, webhookService — peu couverts

2.3 Rust (Chat, Stream)

  • Clippy : 0 warnings (déjà vital)
  • Tests : Déjà dans TMT vital
  • Pas de changement structurel prévu

3. ÉLIMINATION DES FAUX POSITIFS

Élément Action Argument
npm run test -- --run || true Supprimer Tests qui passent malgré régression = illusion
Snapshots sans assertion sémantique Supprimer ou remplacer Snapshots décoratifs ; ajouter expect sur comportement
Tests qui ne testent que React/framework Supprimer Redondants avec tests framework
PlaylistErrorBoundary.test.tsx (jest.spyOn) Remplacer par vi.spyOn Incohérence Vitest
Tests Go auth/RBAC avec mocks cassés Réparer Sinon les exclure explicitement (documenté)

4. RÉDUCTION DU MOCKING

Objectif : remplacer le mocking par de la composition testable.

Action Détail
Extraction de ports/adapters Interfaces pour authService, apiClient — injection en tests
MSW ciblé Garder MSW pour les handlers HTTP ; ne pas mocker 10+ modules par test
Doubles de test minimaux Backend : interfaces Go déjà présentes ; utiliser des implémentations stub
Unifier auth Une source (Store) → un mock au lieu de deux

Critère : si un test nécessite > 5 mocks, le design est toxique.


5. ORCHESTRATION TMT

5.1 État actuel (diagnostic)

Aspect État Détail
TMT utilisé en CI Non La CI n'appelle jamais tmt run
Types de tests TMT Partiel Build, bundle_size, build_perf, no_critical_js ; Go unit (internal) ; Rust clippy/test
Vitest Hors TMT Exécuté directement dans ci.yml avec || true
Playwright Hors TMT Workflow séparé, sans working-directory: apps/web
Contournement CI directe go test, npm run test, npx playwright test sans TMT

Conclusion : TMT est une couche déclarative sous-exploitée. La CI est une projection ad-hoc, pas fidèle à TMT.

5.2 Rôle cible de TMT

TMT devient :

  • Point d'entrée unique pour tous les tests
  • Garant de l'ordre, des dépendances, des profils (local / CI / nightly)

5.3 Modélisation TMT cible

tmt/
├── plans/
│   ├── vital.fmf           # Tier 1 — bloque tout
│   ├── integration.fmf     # Tier 2 — nécessite infra (DB, Redis)
│   └── nightly.fmf         # Tier 3 — E2E, contract, visuels
├── tests/
│   ├── frontend/
│   │   ├── build.sh
│   │   ├── build_perf.sh
│   │   ├── bundle_size.sh
│   │   ├── no_critical_js.sh
│   │   └── unit.sh         # NOUVEAU — npm run test -- --run
│   ├── frontend-e2e/
│   │   └── playwright.sh   # NOUVEAU — npx playwright test
│   ├── backend/
│   │   ├── unit.sh
│   │   ├── integration.sh
│   │   ├── core_isolation.sh
│   │   ├── startup_time.sh
│   │   └── memory_budget.sh
│   └── services/
│       ├── rust_clippy.sh
│       └── rust_test.sh
└── README.md

Variables d'environnement explicites :

Variable Valeur Rôle
GOMAXPROCS 1 Low-power backend
LIBGL_ALWAYS_SOFTWARE 1 GPU désactivé
RUST_BACKTRACE 0 Bruit minimisé
VEZA_TEST_DB_URL (optionnel) Intégration
VEZA_E2E_API_URL (optionnel) E2E

Artefacts de sortie :

Artefact Emplacement Usage
Coverage Go veza-backend-api/coverage.out Rapport, seuils
Coverage Vitest apps/web/coverage/ Rapport, seuils
Playwright report apps/web/playwright-report/ Debug E2E

5.4 Plans TMT

Plan Tier Contenu Bloquant
vital 1 build, bundle_size, build_perf, no_critical_js, backend unit, rust clippy/test, frontend unit Oui
legacy 2 integration (backend), startup_time, memory_budget Non (warning)
nightly 3 E2E Playwright, contract, Storybook audit Non

Changement majeur : frontend/unit.sh ajouté au plan vital. Exécute npm run test -- --run sans || true.


6. COUVERTURE & TMT

Plan Couverture produite Agrégation Seuils
vital vitest run --coverage, go test -coverprofile Rapports séparés par composant Évalués en CI ; échec si seuils non atteints
legacy Idem Idem Indicateur
nightly E2E (pas de coverage classique) Playwright HTML report Binaire (pass/fail)

Agrégation : pas de rapport global unique. Chaque composant (frontend, backend) a ses seuils. CI échoue si un seuil est violé.

Aucun || true. Aucune exception silencieuse.


7. INTÉGRATION CI

Principe : La CI est une projection fidèle de l'exécution TMT.

7.1 Règle

La CI ne doit jamais appeler directement vitest, go test, playwright.
Elle appelle toujours tmt run plan --name /vital (ou équivalent).

7.2 Schéma cible

# .github/workflows/ci.yml (simplifié)
jobs:
  test:
    steps:
      - uses: actions/checkout@v4
      - name: Install TMT
        run: pip install tmt
      - name: Run Vital Tests
        run: tmt run plan --name /vital
        # Plus de go test, npm test, etc. directs

7.3 Workflows à corriger/supprimer

Workflow Action Raison
ci.yml Remplacer jobs par tmt run Point d'entrée unique
frontend-ci.yml Supprimer Chemin apps/web-frontend inexistant
backend-ci.yml Supprimer Chemin apps/backend-api inexistant
playwright.yml Intégrer dans TMT nightly ou garder séparé avec working-directory: apps/web E2E nécessite runtime différent

8. FEUILLE DE ROUTE

Phase 1 — Rétablissement de la vérité (12 semaines)

Priorité Action Effort
P0 Supprimer `
P0 Corriger playlist_duplicate_transaction_test.go:80 (compile) 2 h
P0 Exclure/corriger tests Go qui paniquent (testutils, RoomService) 4 h
P1 Ajouter working-directory: apps/web à playwright.yml 15 min
P1 Supprimer frontend-ci.yml, backend-ci.yml (ou corriger chemins) 15 min

Objectif : tests qui échouent = build rouge assumé.

Phase 2 — Couverture ciblée (13 mois)

Priorité Action Effort
P1 Réparer tests auth middleware (Go) 8 h
P1 Ajouter tmt/tests/frontend/unit.sh et l'intégrer au plan vital 2 h
P1 Faire appeler la CI tmt run plan --name /vital 4 h
P2 Validation seuils coverage en CI (par domaine) 8 h
P2 Remplacer jest.spyOn par vi.spyOn 2 h
P2 Tests branches d'erreur sur auth, RBAC, client API 24 h

Objectif : ajout de tests uniquement sur zones critiques ; suppression de tests toxiques.

Phase 3 — Stabilisation (24 semaines)

Priorité Action Effort
P2 Temps d'exécution suite unitaire < 2 min (frontend) Variable
P2 Flakiness = 0 (audit, correction) Variable
P3 Découper client.ts (modules testables) 40 h
P3 Unifier auth (Context → Store) 24 h

Objectif : temps maîtrisé ; zéro tolérance au flaky.


9. LIVRABLE — LISTE PRIORISÉE

9.1 Tests à écrire

Domaine Fichier / Zone Type Priorité
Auth internal/core/auth Unit (chemins erreur) P0
RBAC rbac_auth_middleware_test.go Corriger mocks P0
Client API client.ts (après découpage) Interceptors, retry P1
Commerce marketplaceService, cartStore Unit P1
Webhooks webhookService, handlers Unit + integration P1
Optimistic optimisticUpdates.ts Rollback, invalidation P2

9.2 Tests à corriger

Test Action Priorité
auth_middleware_test.go Aligner mocks avec ValidateSession P0
rbac_auth_middleware_test.go Aligner mocks HasRole/HasPermission P0
PlaylistErrorBoundary.test.tsx jest → vi P1
auth.integration.test.tsx Réduire mocks, scinder P2

9.3 Tests à supprimer

Test Raison Priorité
Snapshots sans assertion sémantique Illusion de couverture P2
Tests redondants (framework only) Aucune valeur métier P2
Tests orphelins (jest.config.js si Jest inutilisé) Nettoyage P3

10. RÉSUMÉ EXÉCUTIF

Principe Décision
Couverture Différenciée par domaine ; domaines critiques ≥ 90% branches
Faux positifs Suppression de || true ; tests cassés = build rouge
Mocking Réduction ; composition testable ; ≤ 5 mocks par test
TMT Point d'entrée unique ; CI appelle tmt run
Phases 1. Vérité → 2. Couverture ciblée → 3. Stabilisation

Phrase de clôture : Une régression significative ne peut plus passer inaperçue — à condition que les phases 1 et 2 soient exécutées sans compromis.


Fin du document.