TESTS SANS CASSER
Prérequis
- Vitest (ou Jest) configuré avec `@testing-library/react`
- `strict: true` dans tsconfig et CI locale `pnpm test`
- Rule tests dans `.cursor/rules/testing.mdc` ou exemple de test existant dans le repo
- Fichier source cible avec branches métier identifiables (pas uniquement du rendu statique)
Les tests générés à la va-vite mockent tout le module et contournent `strict` via `as any`, ce qui produit des faux positifs rassurants. En encodant Vitest, Testing Library et vos helpers typés dans une rule `testing.mdc`, vous alignez l’agent sur des tests maintenables qui échouent quand le contrat TypeScript change.
Cadrer la rule testing.mdc
Créez `.cursor/rules/testing.mdc` avec globs `**/*.test.ts`, `**/*.test.tsx`. Exigez : `import { describe, it, expect, vi } from 'vitest'`, `render` / `screen` Testing Library pour l’UI, `userEvent` pour les interactions.
Interdisez `@ts-ignore`, `as any`, et les snapshots seuls pour valider une UI. Autorisez `satisfies` et les helpers typés du repo (`createMockPost()`, factories). Référez un fichier test exemplaire @mentionné dans la rule.
Rappelez la politique couverture agence : prioriser chemins métier et régressions connues, pas 100 % sur les pages marketing.
Générer et affiner les tests
Sélectionnez le fichier source ou @mentionnez-le. Prompt : « Tests pour branches critiques : validation, erreur réseau, état vide. Un describe par fonction exportée. » Relisez les mocks : trop larges masquent les régressions.
Lancez `pnpm test chemin/fichier.test.ts`. En cas d’échec, coller l’erreur complète : « corrige le test sans assouplir le typage ». Itérez test par test, pas regenerate all.
Pour composants async Server-only, testez la logique extraite dans `lib/` plutôt que le RSC directement — ou utilisez des tests d’intégration ciblés si déjà en place.
Intégrer à la CI et la PR
Vérifiez que les nouveaux tests passent en CI locale (`pnpm run verify:*` si script agence). Mentionnez dans la PR quels chemins métier sont couverts.
Refusez les tests qui dupliquent l’implémentation (assertion sur détail interne) : préférez comportement observable (texte, rôle, callback).
Erreurs fréquentes
Accepter `expect(result as any).toBe(...)` pour faire passer Vitest.
Mock du module entier alors qu’un spy sur une fonction suffit.
Tests UI sans `await userEvent.click` : race conditions flaky.
Générer 200 lignes de tests superficiels pour gonfler la couverture.
Oublier `cleanup` implicite : Testing Library moderne le gère, mais pas les timers `vi.useFakeTimers` mal reset.
Ce qu’il faut retenir
Rule `testing.mdc` + exemple typé = tests sans contournement strict.
Mocks minimaux, assertions comportementales, pas de snapshot seul UI.
`pnpm test` local avant PR ; itération sur échecs un par un.
Couverture ciblée chemins métier, pas chiffre vanity sur le marketing.
FAQ
Priorisez parsers, validateurs, hooks métier et régressions ticketées. 100 % sur les pages vitrine n’est pas l’objectif ; la confiance sur les chemins critiques si.
Adaptez imports et config dans `testing.mdc`. Le principe reste : pas de `any`, Testing Library pour l’UI, mocks ciblés.
Extrayez la logique pure dans `lib/` testable. Pour l’Action elle même, tests d’intégration ou e2e selon votre stack — précisez-le dans la rule pour éviter des mocks HTTP fragiles.