# AUDIT DES TESTS ET DE LA COUVERTURE — VEZA **Date** : 2025-02-10 **Mandat** : Comité d'architecture — décision sur la fiabilité à moyen terme et la valeur de la base de tests **Périmètre** : Intégralité du dépôt (monorepo) **Ton** : Sans complaisance. Faits observables > interprétations. --- ## 0. SYNTHÈSE EXÉCUTIVE (CTO) ### Verdict global **La base de tests de Veza n'est pas un actif fiable.** Elle ressemble à un dispositif de sécurité (Vitest, Playwright, Jest, Storybook, MSW, 261 tests Go, 288+ tests frontend) mais, en pratique : - **Les tests unitaires frontend bloquent désormais le build** — le `|| true` a été supprimé (`.github/workflows/ci.yml:148`). - **Le backend contient 445 échecs documentés** (TEST_FAILS.md), dont 23 P0, 176 tests skippés, 6 panics, 3 erreurs de compilation. - **Les tests critiques d'authentification (auth middleware, RBAC)** échouent en série (mock expectations non satisfaites). - **Les workflows frontend-ci et backend-ci pointent vers des chemins inexistants** (`apps/web-frontend`, `apps/backend-api`). - **La couverture mesurée (seuils 80%) n'est pas vérifiée en CI** — aucune étape n'exige le respect des seuils. En résumé : **une couverture élevée pourrait masquer une faible résilience.** La CI frontend protège désormais le main (tests bloquants). Le backend reste fragilisé par les échecs documentés et les tests d'intégration en quarantaine. ### Indicateurs clés | Indicateur | État | Commentaire | |------------|------|-------------| | Tests unitaires bloquants | ✅ Oui | `npm run test -- --run` — sans `\|\| true` | | Tests Go exécutables en CI | ⚠️ Partiel | Seulement `handlers` et `services` avec `-short` | | Tests E2E en CI | ⚠️ Incertain | playwright.yml sans `working-directory: apps/web` | | Couverture vérifiée | ❌ Non | Pas de step qui valide les seuils | | Tests auth / RBAC | ❌ Échouent | Mocks fragiles | | Tests d'intégration | 🟡 Quarantaine | Beaucoup skippés ou manuels | ### Recommandation stratégique **Court terme (1–2 semaines)** : Corriger les chemins des workflows frontend-ci/backend-ci, rendre les tests Go exécutables (exclure les packages qui paniquent), et corriger l'erreur de compilation `playlist_duplicate_transaction_test.go`. **Moyen terme (1–3 mois)** : Réparer les tests auth/RBAC, réintégrer les tests d'intégration critiques, et ajouter une étape de validation des seuils de couverture. **Long terme** : Restructurer la pyramide de tests, éliminer la dette de mocks fragiles, et aligner l'architecture sur la testabilité. --- ## 1. PÉRIMÈTRE D'ANALYSE ### 1.1 Langages et frameworks | Composant | Langage | Framework | Outil de test | |-----------|---------|-----------|---------------| | **Frontend** | TypeScript | React 18, Vite 7, TanStack Query, Zustand | Vitest, Playwright, MSW | | **Backend API** | Go | Echo/Gin (serveur HTTP) | `go test` | | **Chat Server** | Rust | Actix/Axum | `cargo test` | | **Stream Server** | Rust | idem | `cargo test` | | **Shared** | Rust | veza-common | `cargo test` | ### 1.2 Architecture - **Monorepo** : `apps/web`, `veza-backend-api`, `veza-chat-server`, `veza-stream-server`, `veza-common`, `packages/`, `fixtures/` - **Front** : SPA React, feature-based, ~2500+ fichiers TS/TSX - **Back** : API REST Go, services, handlers, middleware, migrations SQL - **Rust** : Services temps réel (chat, streaming) ### 1.3 Ce qui est testé vs non testé | Catégorie | État | Fichiers / Indices | |-----------|------|--------------------| | **Testé** | Composants UI, hooks, utils, services frontend, handlers/services Go | ~288 fichiers `.test.ts(x)`, ~261 `*_test.go`, E2E Playwright | | **Implicitement non testable** | Client API monolithique (2238 lignes), main.tsx (278 lignes), correctifs CSS globaux | `client.ts`, `main.tsx`, `fix-*.css` | | **Non testé par choix** | Cmd packages Go (migrate, generate-config-docs, etc.) | `t.Skip()` dans packages | | **Non testé par négligence** | Zones critiques : auth dual (Context + Store), RBAC, permissions, webhooks, marché | Peu de tests sur `authStore` vs `AuthContext`, `webhookService` | --- ## 2. CARTOGRAPHIE DES TESTS EXISTANTS ### 2.1 Typologie #### Tests unitaires purs | Composant | Nombre approx. | Répartition | Ratio code critique | |-----------|----------------|-------------|---------------------| | **Frontend** | ~250+ | `utils/`, `hooks/`, `components/ui/`, `features/auth/`, `features/playlists/` | Bon sur utils, hooks, auth. Faible sur services API, stores | | **Backend** | ~150+ | `internal/config/`, `internal/response/`, `internal/validators/`, nombreux handlers | Inégale. Config bien couverte. Handlers/services partiellement | #### Tests unitaires avec mocks lourds | Composant | Exemples | Problème | |-----------|----------|----------| | **Frontend** | `LoginForm.test.tsx`, `auth.integration.test.tsx` | Mocks de `authStore`, `authService`, `useAuth`, `useLogin`, etc. — 10+ mocks par fichier | | **Backend** | `auth_middleware_test.go`, `rbac_auth_middleware_test.go` | Mocks `ValidateSession`, `HasRole`, `HasPermission` — **échouent** (`0 out of 1 expectation(s) were met`) | #### Tests d'intégration | Composant | Fichiers | État | |-----------|----------|------| | **Frontend** | `auth.integration.test.tsx`, `playlist.integration.test.tsx`, `collaboration.integration.test.tsx`, `trackUpload.integration.test.tsx` | Présents mais dépendent de mocks MSW | | **Backend** | `tests/integration/*.go` | Quarantaine. `api_health_test.go` corrigé. `upload_async_polling_test.go` partiellement. `playlist_duplicate_transaction_test.go` — **erreur de compilation** (ligne 80) | #### Tests contractuels | Composant | Fichier | État | |-----------|---------|------| | **Backend** | `tests/contract/api_contract_test.go` | Présent. Non exécuté en CI standard (nécessite `-tags integration`) | #### Tests end-to-end | Composant | Fichiers | État | |-----------|----------|------| | **Frontend** | `e2e/tests/*.spec.ts` (auth, smoke, playlists, profile, upload, mobile, cross-browser, ui-audit, visual) | Playwright. `globalSetup` requiert API disponible. `workers: 1` (rate limiting). | | **Tools** | `tools/tests/e2e/specs/*.spec.ts` | Auth, chat, docs, files, profile, stream | | **Desktop** | `veza-desktop/tests/e2e/*.spec.ts` | Transcoding, library, playlists, settings | #### Tests de non-régression | Type | Fichiers | État | |------|----------|------| | **Visuels** | `e2e/tests/visual/*.spec.ts`, `visual-regression.spec.ts` | Playwright snapshots. Baselines dans `__snapshots__/` | | **Storybook** | `scripts/audit-storybook.js`, `test:storybook:playwright` | Audit console/network errors. Workflow séparé | #### Tests de snapshot | Composant | Usage | État | |-----------|-------|------| | **Frontend** | Vitest snapshots — peu utilisés explicitement | Snapshot tests non dominants | | **E2E** | Playwright `toHaveScreenshot()` | Utilisé pour visual regression | ### 2.2 Localisation et structure #### Organisation des dossiers ``` # Frontend apps/web/src/ ├── __tests__/ # Tests transversaux (accessibility, contrast) ├── test/ # setup.ts, test-utils, setup.test.tsx ├── mocks/ # handlers.ts (MSW), test-setup.ts ├── features/*/__tests__/ # Intégration par feature ├── **/*.test.ts(x) # Colocalisés avec le code └── e2e/ # Playwright (global-setup, tests, utils) # Backend veza-backend-api/ ├── internal/**/*_test.go # Colocalisés ├── tests/ # integration, contract, security, transactions, etc. └── docs/ # TEST_FAILS.md, QUARANTINE.md ``` #### Cohérence des conventions - **Frontend** : `*.test.tsx` ou `*.test.ts` à côté du fichier. Cohérent. - **Backend** : `*_test.go` standard Go. Cohérent. - **E2E** : `*.spec.ts` dans `e2e/tests/`. Cohérent. #### Signes problématiques | Signe | Fichier / Indice | |-------|-------------------| | **Tests orphelins** | `jest.config.js` présent alors que `package.json` utilise `vitest` — configuration dupliquée | | **Tests redondants** | `PlaylistErrorBoundary.test.tsx` utilise `jest.spyOn` alors que le projet est sur Vitest (`vi` attendu) | | **Tests trop larges** | `auth.integration.test.tsx` — 600+ lignes, mocks massifs | | **Tests trop spécifiques** | Certains tests UI vérifient des détails d'implémentation (classes CSS, structure DOM) | --- ## 3. QUALITÉ INTRINSÈQUE DES TESTS ### 3.1 Lisibilité | Critère | Évaluation | Exemples | |---------|------------|----------| | **Clarté de l'intention** | Inégale | `LoginForm.test.tsx` : intentions claires. `auth.integration.test.tsx` : nécessite de lire l'implémentation pour comprendre les mocks | | **Lisibilité des données** | Correcte | Factories, fixtures dans `fixtures/`. Parfois données inline | | **Explicitation des cas limites** | Partielle | `serviceErrorHandler.test.ts`, `apiErrorHandler.test.ts` couvrent erreurs. Beaucoup de tests ne couvrent que le chemin heureux | ### 3.2 Robustesse | Problème | Indice | |----------|--------| | **Dépendance à l'ordre** | Vitest exécute en parallèle par défaut. Pas de dépendance explicite à l'ordre | | **Dépendance à l'horloge** | `MockWebSocket` utilise `setTimeout(100)` — délai fixe. Risque de flakiness si timeout trop court | | **Dépendance au réseau** | E2E `globalSetup` requiert API. Sans API, les tests E2E échouent | | **Dépendance au système de fichiers** | Handlers MSW, pas de dépendance directe | | **Flakiness** | Backend : 14 race conditions (logging), 12 timeouts. Tests middleware auth : couplage fort aux mocks | ### 3.3 Couplage | Problème | Impact | |----------|--------| | **Mocks auth** | Toute refactorisation de l'auth (Context vs Store) casse les tests | | **Structure DOM** | `screen.getByText(/resend verification email/i)` — couplé au libellé. Changement de traduction = échec | | **Mock expectations** | Backend : `FAIL: 0 out of 1 expectation(s) were met` — mocks trop stricts, implémentation a changé | --- ## 4. ANALYSE DE LA COUVERTURE ### 4.1 Données brutes | Composant | Outil | Seuils configurés | Vérification en CI | |-----------|-------|-------------------|--------------------| | **Frontend** | Vitest (v8) | branches: 80, functions: 80, lines: 80, statements: 80 | ⚠️ Non vérifié (pas de step `--coverage` en CI) | | **Frontend** | Jest (legacy) | Idem | Jest non utilisé (Vitest actif) | | **Backend** | `go test -coverprofile` | — | ✅ Workflow `test-coverage.yml` (séparé, artifacts) | **Chiffre global** : Non mesuré de manière fiable en CI. Les seuils Vitest sont définis mais aucune étape CI n'exécute `--coverage` ni ne valide les seuils. ### 4.2 Illusions de couverture | Illusion | Indice | |----------|--------| | **Code couvert mais jamais asserté** | Tests qui render sans `expect` sur le comportement. Risque de tests "passants" qui ne valident rien | | **Chemins heureux uniquement** | Beaucoup de tests ne mockent que le succès. `handleServiceError`, `apiErrorHandler` font exception | | **Branches d'erreur non exercées** | `client.ts` (2238 lignes) : interceptors, retry, refresh, offline queue — peu de tests directs | | **Couverture élevée ≠ résilience** | Seuils 80% pourraient être atteints sur des fichiers peu critiques (utils) tout en laissant le cœur métier (auth, RBAC, payments) sous-testé | --- ## 5. ANALYSE PAR DOMAINE MÉTIER ### 5.1 Logique métier à fort risque | Domaine | Niveau de couverture | Type de tests | Faille potentielle | |---------|----------------------|---------------|---------------------| | **Auth / Sessions** | Moyen (front) ; Échec (back) | Unitaires avec mocks ; Middleware Go | Backend : tests auth middleware échouent. Double source auth (Context + Store) non testée | | **RBAC / Permissions** | Échec | `rbac_auth_middleware_test.go` | Mocks `HasRole`, `HasPermission` non satisfaits. Droits non validés | | **Upload / Tracks** | Partiel | Intégration quarantaine, handlers | `playlist_duplicate_transaction_test.go` ne compile pas. Upload async partiellement testé | | **Commerce / Marketplace** | Faible | Peu de tests dédiés | `marketplaceService`, `cartStore` — `cartStore.test.ts` présent. Services commerce peu couverts | | **Webhooks** | Faible | `webhook_service_test.go`, `webhook_handlers_test.go` | Présents. Pas de test E2E de livraison | | **Synchronisation d'état** | Moyen | Offline queue, optimistic updates | `optimisticUpdates.ts` documenté. Peu de tests sur rollback, invalidation | ### 5.2 Invariants métier - **Propriété des ressources** : `ownership_integration_test.go` présent. Résultat non vérifié en CI. - **Transactions** : `rbac_transaction_test`, `social_transaction_test`, `playlist_duplicate_transaction_test` — dernier ne compile pas. --- ## 6. TESTABILITÉ DE L'ARCHITECTURE ### 6.1 Points favorables - **MSW** : Handlers centralisés (~1682 lignes). Développement et tests sans backend. - **Feature-based** : Structure modulaire. Features isolables. - **React Query** : Fetch centralisé. Mockable via MSW. - **Dependency injection** : Go utilise des interfaces. Services injectables. ### 6.2 Points bloquants | Problème | Fichier / Indice | |----------|-------------------| | **Singletons globaux** | `authStore` (Zustand) + `AuthContext` — deux sources. Tests doivent mocker les deux | | **Dépendances cachées** | `client.ts` — interceptors, retry, CSRF, offline queue. Pas de découpage. Difficile à tester unitairement | | **Effets de bord** | `main.tsx` — waitForStylesheets, fixDisplayIssues, fixInputFocus. Init complexe | | **Mocking excessif** | Tests auth : 10+ `vi.mock()`. Toute évolution casse les tests | ### 6.3 Mélange orchestration / logique - **Pages** : Certaines pages font fetch direct (`useState` + `useEffect` + `apiClient`) au lieu de React Query. Difficile à isoler. - **Client API** : Logique métier (retry, refresh, validation) mélangée avec transport. Pas de séparation nette. --- ## 7. DETTE DE TEST ### 7.1 Classification | Dette | Gravité | Coût de correction | Impact sur vélocité | |------|---------|-------------------|--------------------| | ~~Tests non bloquants~~ | ~~Critique~~ | — | ✅ **Corrigé** : tests bloquants | | **Tests Go auth/RBAC échouants** | Critique | Moyen (corriger mocks) | Blocage si activés | | **176 tests skippés (Backend)** | Élevée | Élevé | Inconnu — tests ignorés | | **Config Jest obsolète** | Faible | Faible (supprimer) | Confusion | | **playwright.yml sans working-directory** | Moyenne | Faible | E2E peuvent échouer si exécutés depuis la racine | | **Workflows frontend/backend ci inutilisables** | Moyenne | Faible (corriger chemins) | Aucun — jamais déclenchés | ### 7.2 Tests lents - **Vitest** : Timeout observé lors de l'exécution (commande interrompue après 120s). Suite conséquente. - **Backend** : `go test ./internal/...` timeout également. Suite très volumineuse. - **E2E** : `workers: 1` — séquentiel. Timeout 60s par test. ### 7.3 Tests fragiles - **Backend auth** : Changement de signature ou comportement de `ValidateSession` casse tous les tests middleware. - **Frontend** : Libellés i18n en dur dans les assertions. Changement de traduction = échec. - **PlaylistErrorBoundary** : Utilise `jest.spyOn` (Jest) au lieu de `vi.spyOn` (Vitest) — incohérence. --- ## 8. CI / AUTOMATISATION ### 8.1 Workflows actifs | Workflow | Déclenchement | Contenu | Problème | |----------|---------------|---------|----------| | **ci.yml** | push/PR main, remediation/*, feature/mvp-complete | Backend (vet, lint, test -short, build), Rust (fmt, build, test chat), Frontend (lint, format, typecheck, **test** (bloquant), build) | ✅ Tests frontend bloquants | | **playwright.yml** | push/PR main, master | `npx playwright test` | Pas de `working-directory: apps/web`. Dépendances `npm ci` à la racine — peut échouer | | **storybook-audit.yml** | push/PR apps/web | build-storybook, serve, audit-storybook.js | Correct | | **test-coverage.yml** (backend) | push/PR main, develop | `go test -coverprofile` | Correct. Artifacts. | | **frontend-ci.yml** | paths: apps/web-frontend | pnpm test | **Chemin inexistant** (apps/web-frontend) | | **backend-ci.yml** | paths: apps/backend-api | go test | **Chemin inexistant** (apps/backend-api) | ### 8.2 Fréquence, temps, seuils - **Fréquence** : À chaque push/PR sur les branches configurées. - **Temps** : Non mesuré. Playwright timeout 60 min. - **Seuils bloquants** : Tests unitaires frontend **bloquent** le build. Couverture : pas de seuils vérifiés. Backend : tests exécutés, résultats bloquants si échecs. ### 8.3 Protection du main **La CI frontend protège désormais le main** — les tests unitaires bloquent le build. **La CI backend reste fragile** : exécution d'un sous-ensemble (`handlers`, `services`, `-short`). Les tests auth/RBAC qui échouent font partie des packages exécutés — la CI backend peut être instable ou les tests skippés. À clarifier. --- ## 9. RISQUES MAJEURS IDENTIFIÉS ### R1. Régression auth / RBAC non détectée - **Probabilité** : Élevée - **Impact** : Critique (accès non autorisé, fuite de données) - **Indice** : Tests auth middleware et RBAC échouent. Toute modification du flux auth n'est pas validée par les tests. ### R2. Déploiement de code cassé - **Probabilité** : Réduite (frontend) - **Impact** : Élevé - **Indice** : Tests frontend bloquants — correction appliquée. Backend : risque persistant si tests skippés ou exclus. ### R3. Désynchronisation auth (Context vs Store) - **Probabilité** : Moyenne - **Impact** : Élevé (comportement incohérent, bugs subtils) - **Indice** : Double source de vérité. Aucun test ne valide la cohérence. ### R4. Régression API non détectée - **Probabilité** : Moyenne - **Impact** : Élevé - **Indice** : Tests d'intégration en quarantaine. Contract tests non exécutés en CI standard. Client API monolithique peu testé. ### R5. E2E fragiles ou non exécutés - **Probabilité** : Élevée - **Impact** : Moyen - **Indice** : `playwright.yml` sans working-directory. `globalSetup` requiert API. Workers=1. Pas de preuve que les E2E passent en CI. --- ## 10. RECOMMANDATIONS STRATÉGIQUES ### 10.1 Court terme (1–2 semaines) 1. ~~Supprimer `|| true`~~ — **Fait** : les tests frontend bloquent désormais. 2. **Corriger les chemins** des workflows `frontend-ci.yml` et `backend-ci.yml` (ou les supprimer s'ils sont obsolètes). 3. **Ajouter `working-directory: apps/web`** au workflow `playwright.yml`. 4. **Exclure les packages Go qui paniquent** de la CI : `internal/testutils` (TestRunParallelTests), ou les corriger. 5. **Corriger l'erreur de compilation** `playlist_duplicate_transaction_test.go:80` (utilisation incorrecte de `file`). ### 10.2 Moyen terme (1–3 mois) 1. **Réparer les tests auth/RBAC** : Aligner les mocks sur l'implémentation actuelle ou refactoriser les mocks pour qu'ils soient moins fragiles. 2. **Réintégrer les tests d'intégration critiques** : `api_health_test.go` (déjà corrigé), contract tests. Exécuter en CI avec tag `integration` sur un environnement dédié. 3. **Ajouter une étape de validation des seuils de couverture** : `vitest run --coverage` et fail si en dessous de 80% sur les répertoires critiques (features/auth, features/playlists, services). 4. **Unifier auth** : Éliminer la double source (Context + Store). Réduire le coût des mocks dans les tests. 5. **Remplacer `jest.spyOn` par `vi.spyOn`** dans tous les tests frontend (ex. PlaylistErrorBoundary.test.tsx). 6. **Découper `client.ts`** : Extraire interceptors, retry, validation en modules testables. ### 10.3 Long terme 1. **Pyramide de tests** : Rééquilibrer — plus de tests unitaires ciblés (logique pure), moins de tests avec mocks massifs. Tests d'intégration avec MSW pour les flux critiques. 2. **Tests par contrat** : OpenAPI comme source de vérité. Tests contractuels automatisés en CI. 3. **Environnement de test dédié** : Base de données, Redis, services pour les tests d'intégration backend. CI nightly ou staging. 4. **Politique de couverture par domaine** : 80% sur auth, RBAC, commerce. 60% sur le reste. Métriques par module. --- ## 11. MÉTRIQUES DE SUIVI Au-delà du simple % de coverage, proposer : | Indicateur | Cible | Mesure | |------------|-------|--------| | **Taux de tests bloquants** | 100% | Nombre de branches où les tests peuvent échouer sans bloquer → 0 | | **Taux de tests passants (Backend)** | 95% | (Total - Skip - Fail) / Total | | **Couverture des branches d'erreur** | 70% | Branches catch/error exercées / total | | **Temps de suite unitaire** | < 2 min | Frontend Vitest | | **Temps de suite E2E** | < 15 min | Playwright (chromium uniquement en CI) | | **Dette de skip** | -10% / mois | Réduire le nombre de tests skippés | | **Flakiness** | 0% | Nombre de tests flaky sur 10 runs | --- ## 12. RÉFÉRENCES ET FICHIERS CITÉS | Fichier | Rôle | |---------|------| | `apps/web/package.json` | Scripts test, vitest | | `apps/web/jest.config.js` | Config obsolète (Jest) | | `apps/web/vitest.config.ts` | Config Vitest, coverage, thresholds | | `apps/web/src/test/setup.ts` | Setup Vitest, mocks | | `apps/web/src/mocks/handlers.ts` | MSW handlers | | `apps/web/e2e/global-setup.ts` | Playwright auth | | `apps/web/playwright.config.ts` | Config E2E | | `.github/workflows/ci.yml` | Pipeline principal | | `.github/workflows/playwright.yml` | E2E | | `.github/workflows/storybook-audit.yml` | Storybook | | `veza-backend-api/tests/integration/QUARANTINE.md` | Classification tests | | `veza-backend-api/docs/TEST_FAILS.md` | Inventaire 445 échecs | | `veza-backend-api/.github/workflows/test-coverage.yml` | Coverage Go | --- ## 13. FEUILLE DE ROUTE PRIORISÉE | Priorité | Action | Effort | Impact | |----------|--------|--------|--------| | ~~P0~~ | ~~Supprimer `\|\| true`~~ | — | ✅ **Fait** | | P0 | Corriger `playlist_duplicate_transaction_test.go` (compile) | 2 h | Critique | | P1 | Ajouter working-directory à playwright.yml | 30 min | Élevé | | P1 | Corriger ou supprimer frontend-ci/backend-ci workflows | 30 min | Moyen | | P1 | Exclure/corriger tests Go qui paniquent | 4 h | Élevé | | P2 | Réparer tests auth middleware (Go) | 8 h | Critique | | P2 | Validation seuils coverage en CI | 2 h | Élevé | | P2 | Remplacer jest par vi dans tests frontend | 2 h | Moyen | | P3 | Découper client.ts | 40 h | Moyen | | P3 | Unifier auth (Context vs Store) | 24 h | Élevé | --- **Fin du rapport.**