--- title: Backend — Risques & vigilance : Tests domain: backend bucket: risques tags: [tests, vitest, isolation, env-vars, flakiness] applies_to: [analysis, implementation, review, debug] severity: high validated_on: 2026-05-02 source_projects: [RL799_V2] --- # Backend — Risques & vigilance : Tests > Extrait de la base de connaissance Lead_tech. Voir `knowledge/backend/risques/README.md` pour l'index complet. --- ## `vi.stubEnv` sans restauration — fuite env vars inter-fichiers ### Risques - Un test qui stub une env var dans `beforeAll` sans `vi.unstubAllEnvs()` en `afterAll` affecte silencieusement tous les fichiers exécutés après lui dans le même process - En séquentiel (`maxWorkers: 1`), l'ordre est déterministe et la fuite est invisible — la suite passe au vert - En passant à `maxWorkers > 1`, les env vars stubbées sont partagées entre workers → tests imprévisibles ### Symptômes - Tests qui passent en isolation mais échouent dans la suite complète, ou inversement - Comportement d'un endpoint qui dépend d'une env définie dans un fichier qui n'a rien à voir - Migration de `maxWorkers: 1` vers `maxWorkers: 4` qui rouge la suite d'un coup ### Bonnes pratiques / mitigations ```typescript beforeAll(() => { vi.stubEnv('RESEND_API_KEY', 'test-key'); }); afterAll(() => { vi.unstubAllEnvs(); }); // Variante encore plus robuste (isolation parfaite par test) : beforeEach(() => { vi.stubEnv('X', 'y'); }); afterEach(() => { vi.unstubAllEnvs(); }); ``` - Détection : `rg "vi\.stubEnv\(" __tests__ | wc -l` doit être ≤ `rg "vi\.unstubAllEnvs\(\)" __tests__ | wc -l` regroupé par fichier - Avant toute migration vers `maxWorkers > 1` : sweep complet `stubEnv` / `unstubAllEnvs` - Contexte technique : Vitest — RL799_V2 24-04-2026 --- ## `maxWorkers: 1` masque les problèmes d'isolation ### Risques - L'exécution séquentielle cache systématiquement tous les bugs d'isolation : `vi.stubEnv` non restaurée, mutations de seed non restaurées, `deleteMany` direct, compteurs globaux non resets - La CI actuelle ne peut pas détecter ces problèmes → faux sentiment de sécurité - Le jour où on veut paralléliser pour gagner du temps, on découvre une dizaine de bugs d'isolation simultanément ### Symptômes - CI verte en `maxWorkers: 1`, rouge dès `maxWorkers > 1` - Tests "verts depuis 6 mois" qui rougent soudainement après un changement de config - Pas de détection possible avant le passage en parallèle ### Bonnes pratiques / mitigations - Tester la parallélisation tôt, même si la suite est petite — passer `maxWorkers: 2` force l'équipe à écrire des tests isolés - Si on hérite d'un projet en `maxWorkers: 1`, ne pas migrer d'un coup. Audit ciblé d'abord : - `grep "vi\.stubEnv\(" / "vi\.unstubAllEnvs\(" / "deleteMany\(" / "TEST_USER\."` pour repérer les patterns suspects - Ajouter un audit "hidden_by_serial_execution" en review de tests : lister les patterns qui marcheraient aujourd'hui mais casseraient en parallèle - Heuristique : projet > 200 tests → impératif de passer en parallèle (sinon CI > 15 min = friction dev majeure) - Contexte technique : Vitest — RL799_V2 24-04-2026 --- ## Flakiness inter-fichiers vitest avec DB partagée ### Risques - Un fichier de tests laisse des artefacts résiduels en DB que le fichier suivant ne s'attend pas à voir : audits orphelins, notifications, entries seed mutées, rate-limiters non resets - Le pattern se "résout" au 2e run par chance (le `beforeEach` finit par nettoyer par effet de bord), donnant une fausse confiance - En CI, un retry automatique masque la vraie cause ### Symptômes - 2-4 tests rouges au 1er run, vert au 2e run sans aucune modification - `vitest run ` vert, suite complète rouge - Compteurs `count({ type: 'X' })` qui tombent sur des résidus d'anciens tests ### Bonnes pratiques / mitigations **Diagnostic** : ```bash # 1. Run isolé sur le fichier suspect pnpm -C apps/api test mon-fichier # 2. 2 runs consécutifs de la suite complète pnpm -C apps/api test && pnpm -C apps/api test # Si 1er rouge / 2e vert → flakiness inter-fichiers ``` **Stratégies par horizon** : - **Court terme** : accepter comme dette connue si le 2e run est stable, documenter dans le commit message - **Moyen terme** : identifier le fichier qui pollue, ajouter le cleanup manquant dans son `afterEach` - **Long terme** : DB-per-worker ou `transactions + rollback` (chantier d'infra dédié, voir `knowledge/backend/patterns/tests.md` pattern template database) **À ne PAS faire** : - Ajouter des `setTimeout` pour "attendre que ça se stabilise" - Wrapper les assertions dans des try/catch silencieux - Marquer les tests `.skip` **Heuristique gravité** : - 1 fail intermittent toutes les 5 runs : acceptable temporairement - 1+ fail systématique au 1er run, vert au 2e : à diagnostiquer mais pas urgent - Fails aléatoires différents à chaque run : urgent (state corruption) - Contexte technique : Vitest / Prisma — RL799_V2 25-04-2026