CommunityRédaction et éditiongithub.com

test-suite-doctor

Compétence d'agent + CLI autonomes pour auditer, réduire et assainir les suites de tests Vitest/Jest gonflées — métriques de couverture par test, minimisation gloutonne, détection de contenu généré par IA, vérification par mutation.

Qu'est-ce que test-suite-doctor ?

Cette compétence d'agent et son ensemble de CLI permettent d'analyser et de réduire drastiquement une suite de tests trop volumineuse (par exemple, plus de 2 000 tests, souvent générés par IA). Elle fournit des métriques de couverture par fichier de test, applique une minimisation gloutonne basée sur le rapport couverture/temps d'exécution, détecte les motifs de « slop » (tests inutiles, tautologies, snapshots vides) et vérifie la qualité par mutation. Compatible avec Vitest et Jest, elle impose un workflow rigoureux : mesure objective, plan de minimisation, revue humaine des suppressions, régénération ciblée et vérification finale du maintien de la couverture. Idéale pour les projets JavaScript/TypeScript qui souffrent de suites de tests héritées, générées automatiquement ou simplement trop lourdes à maintenir.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add JoseAntonioNuevo/test-suite-doctor

Installed? Explore more Rédaction et édition skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Que fait test-suite-doctor ?

Réduisez une suite de tests surdimensionnée (par exemple, plus de 2 000 tests, dont une grande partie générée par IA) en une petite suite de haute qualité tout en conservant une part configurable de la couverture réelle — mesurée, pas devinée.

Règles strictes

  1. Les métriques avant les opinions. Ne proposez jamais de supprimer un test avant que collect et minimize aient produit un plan. Lire le code d'un test et le juger « inutile » n'est pas une preuve — un test d'apparence anodine peut être le seul à couvrir une branche.
  2. Le plan est une proposition, pas un verdict. La couverture ne peut pas voir les contrats d'API, les cas de régression documentés ou les invariants de propriété. Chaque candidat à la suppression est examiné (étape 3) avant d'être supprimé.
  3. Travaillez sur une branche. Avant de supprimer quoi que ce soit, vérifiez que l'arbre de travail est propre et créez une branche (par exemple test-doctor/minimize). Ne supprimez jamais de tests sur un arbre sale ou sur la branche par défaut.
  4. Vérifiez ou annulez. Le travail n'est pas terminé tant que verify ne sort pas avec le code 0. En cas d'échec, régénérez les tests pour les lacunes signalées et revérifiez — ou restaurez les tests supprimés.

Vérification des prérequis (à faire en premier)

  • Node.js ≥ 22 et un package.json utilisant Vitest ou Jest installé localement (node <chemin-compétence>/dist/cli.mjs collect --help).
  • Un fournisseur de couverture doit être installé (Vitest : @vitest/coverage-v8 ; Jest en intègre un). S'il manque, proposez de l'installer comme dépendance de développement.
  • La vérification par mutation nécessite en plus @stryker-mutator/core configuré dans le dépôt cible — elle est facultative, ne l'installez pas sans y être invité.
  • La suite doit être verte avant de commencer. Si l'exécution de référence signale des échecs, informez l'utilisateur et obtenez son accord sur la manière de les traiter avant de minimiser (les tests en échec fournissent une couverture peu fiable).

Toutes les commandes ci-dessous s'exécutent depuis la racine du dépôt cible ; $COMPETENCE est le répertoire de cette compétence. Les artefacts sont placés dans .test-doctor/ (suggérez de l'ajouter au .gitignore).

Workflow

1. MESURER (script — toujours en premier)

node "$COMPETENCE/dist/cli.mjs" collect --cwd .

Détecte le lanceur, exécute la suite complète une fois pour la couverture de référence, puis réexécute chaque fichier de test isolément en enregistrant les lignes/branches couvertes et le temps d'exécution. Écrit .test-doctor/report.json.

  • La granularité par défaut est par fichier de test (l'isolation par test est exacte mais exécute chaque test séparément — proposez --granularity test uniquement pour les suites petites ou déjà réduites, ou limitées avec --filter).
  • Sur une suite de 2 000 tests, cela prend du temps ; exécutez-le en arrière-plan et signalez la progression. Prenez les collectionErrors dans le rapport au sérieux — ces unités bloquent la minimisation par défaut. Si l'utilisateur choisit explicitement --keep-unmeasured, chaque unité affectée est conservée obligatoirement et le plan est marqué comme non fiable.
  • --filter crée une référence volontairement limitée : la collecte, la minimisation et la vérification ne couvrent que les fichiers de test correspondants. Mentionnez cette portée dans chaque recommandation ; il ne s'agit pas d'une garantie pour l'ensemble du dépôt.

2. MINIMISER (script)

node "$COMPETENCE/dist/cli.mjs" minimize --coverage-floor 0.97 --target-count 200

Sélection gloutonne par somme pondérée : conserve de manière itérative l'unité qui apporte le plus de nouvelles lignes/branches couvertes par milliseconde d'exécution jusqu'à atteindre le seuil de couverture. Écrit .test-doctor/plan.json et un fichier lisible .test-doctor/plan.md avec une justification pour chaque unité conservée ou supprimée.

  • Demandez à l'utilisateur ses seuils s'ils ne sont pas précisés ; les valeurs par défaut sont un seuil de lignes à 0,97, aucun seuil de branches, aucun nombre cible. --help liste tous les paramètres.
  • Conservez d'office les tests de contrat/régression connus : --keep 'contract' --keep 'regression' (expression régulière sur l'identifiant de l'unité).
  • Tenez compte du tableau warnings du plan — par exemple, seuil de couverture inaccessible ou nécessitant plus d'unités que le nombre cible. Transmettez-les à l'utilisateur textuellement.

3. RÉVISER (jugement — le vôtre)

Lisez references/slop-patterns.md, puis révisez la liste des suppressions dans plan.md :

  • Sauvegardez tout test qui vérifie un comportement invisible à la couverture : contrats d'API publique, régressions référençant un identifiant de ticket/bug, formulation de messages d'erreur utilisée par les consommateurs, vérifications de propriétés/invariants. Relancez minimize avec des motifs --keep supplémentaires plutôt que de modifier le plan à la main.
  • Confirmez que les autres suppressions sont sûres ; classez-les par motif de slop pour que l'utilisateur voie pourquoi chacun est supprimé (le fichier des motifs contient le catalogue).

Révisez ensuite la liste des conservations par rapport à references/quality-rules.md : les tests conservés qui sentent mauvais (mock du mock, tautologies, snapshots vides) sont réécrits sur place — ils gagnent leur couverture, mais ils doivent le faire proprement.

Ce n'est qu'après cette révision que vous supprimez les fichiers/cas de test supprimés sur la branche. Supprimez les fichiers entiers lorsque toutes leurs unités sont supprimées ; modifiez les fichiers lorsque seuls certains tests à l'intérieur sont supprimés (granularité test).

4. RÉGÉNÉRER (jugement — le vôtre)

Exécutez verify une fois (attendez-vous à un échec éventuel) pour obtenir le rapport des lacunes de couverture, puis écrivez de nouveaux tests pour les fichiers sources les plus touchés listés par verify, en suivant references/quality-rules.md : structure AAA, noms basés sur le comportement, un comportement par test, mocks uniquement aux limites externes. Préférez un test solide couvrant un comportement réel visible par l'utilisateur plutôt que trois tests superficiels.

5. VÉRIFIER (script — valide la fin)

node "$COMPETENCE/dist/cli.mjs" verify --coverage-floor 0.97
# optionnellement, pour les modules critiques uniquement (lent) :
node "$COMPETENCE/dist/cli.mjs" verify --mutation --mutate "src/billing/**/*.ts" --mutation-floor 80

Réexécute la suite, exige qu'elle soit verte et que le taux de conservation des lignes par rapport à la référence atteigne le seuil. Code 0 = terminé ; code 1 = corrigez et relancez (régénérez plus de tests, ou restaurez les suppressions) ; code 2 = problème d'environnement, arrêtez et signalez. Les tests de mutation sont facultatifs par module car ils sont lents — proposez-les pour les modules que l'utilisateur juge critiques.

La version 2 établit une référence de la source couverte, de la configuration du lanceur, du fichier de verrouillage, du lanceur et du fournisseur de couverture. Si verify signale une dérive de provenance, collectez une nouvelle référence. Utilisez --allow-provenance-drift uniquement avec l'accord explicite de l'utilisateur et signalez le verdict résultant comme non fiable. Les références héritées v1 nécessitent également la porte de sortie explicite --allow-legacy-baseline.

Compte rendu

Résumez pour l'utilisateur : unités avant → après, conservation des lignes/branches, temps d'exécution avant → après, motifs de slop trouvés (avec compteurs), tests sauvés de la liste des suppressions et pourquoi, tests régénérés, et verdict final de verify. Incluez le chemin vers plan.md pour la piste d'audit complète.

Modes de défaillance

  • Lanceur non détecté / ambigu → la CLI sort avec le code 2 et fournit des conseils ; passez --runner ou --cwd (monorepos : exécutez par package).
  • Collecte incomplète → corrigez les échecs isolés. Ne les filtrez pas simplement pour faire passer un plan ; un filtre modifie le périmètre déclaré de la référence. --keep-unmeasured est la porte de sortie prudente.
  • verify échoue toujours après régénération → arrêtez la boucle après environ 3 tentatives ; présentez les lacunes résiduelles fichier par fichier et laissez l'utilisateur décider entre abaisser le seuil et conserver plus de tests.
  • La suite était rouge avant de commencer → ne « corrigez » pas les échecs non liés en silence ; signalez-les et convenez d'abord du périmètre.

Skills associés