CommunityRedacción y edicióngithub.com

test-suite-doctor

Audita, minimiza y repara suites de pruebas hinchadas de Vitest/Jest: métricas de cobertura por prueba, minimización voraz, detección de slop generado por IA y verificación de mutación.

¿Qué es test-suite-doctor?

test-suite-doctor es una herramienta avanzada para auditar, reducir y sanear suites de pruebas demasiado grandes (por ejemplo, más de 2000 pruebas, muchas generadas por IA) convirtiéndolas en un conjunto pequeño y de alta calidad. Está diseñada para desarrolladores que trabajan con Vitest o Jest y necesitan mantener una cobertura real sin pruebas redundantes. La herramienta sigue un flujo riguroso: primero mide cobertura y rendimiento por prueba (`collect`), luego aplica un algoritmo voraz de selección para minimizar (`minimize`), después permite revisión manual de pruebas candidatas a eliminar (`review`), regenera pruebas para cubrir brechas (`regenerate`), y finalmente verifica que la suite reducida cumpla los umbrales de cobertura y pase correctamente (`verify`). Soporta verificación de mutación opcional con Stryker, detección de patrones de slop (pruebas inútiles, tautologías, snapshots vacíos) y genera informes detallados. Funciona en Node.js ≥22, requiere una suite verde al inicio, y se ejecuta desde la raíz del repositorio, creando artefactos en `.test-doctor/` y trabajando en una rama separada para evitar riesgos.

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

Installed? Explore more Redacción y edición skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

¿Qué hace test-suite-doctor?

Reduce una suite de pruebas sobredimensionada (p. ej., más de 2000 pruebas, muchas de ellas slop generado por IA) a un conjunto pequeño y de alta calidad, conservando una proporción configurable de cobertura real —medida, no adivinada.

Reglas estrictas

  1. Métricas antes que opiniones. Nunca propongas eliminar una prueba antes de que collect y minimize hayan producido un plan. Leer el código de una prueba y juzgarla como "inútil" no es evidencia: una prueba de aspecto trivial puede ser la única cobertura para una rama.
  2. El plan es una propuesta, no un veredicto. La cobertura no puede ver contratos de API, casos de regresión documentados o invariantes de propiedades. Cada candidato a eliminación se revisa (paso 3) antes de borrarlo.
  3. Trabaja en una rama. Antes de eliminar cualquier cosa, verifica que el árbol de trabajo esté limpio y crea una rama (p. ej., test-doctor/minimize). Nunca elimines pruebas en un árbol sucio o en la rama predeterminada.
  4. Verifica o revierte. El trabajo no está terminado hasta que verify termina con código 0. Si falla, regenera pruebas para los vacíos reportados y vuelve a verificar, o restaura las pruebas eliminadas.

Verificación de requisitos (haz esto primero)

  • Node.js ≥ 22 y un package.json que use Vitest o Jest instalado localmente (node <ruta-del-skill>/dist/cli.mjs collect --help).
  • Debe estar instalado un proveedor de cobertura (Vitest: @vitest/coverage-v8; Jest ya incluye uno). Si falta, ofrece instalarlo como dependencia de desarrollo.
  • La verificación de mutación requiere además @stryker-mutator/core configurado en el repositorio destino; es opcional, no lo instales sin que te lo pidan.
  • La suite debe estar en verde antes de empezar. Si la ejecución base reporta fallos, informa al usuario y obtén su acuerdo sobre cómo manejarlos antes de minimizar (las pruebas que fallan contribuyen con cobertura no fiable).

Todos los comandos siguientes se ejecutan desde la raíz del repositorio destino; $SKILL es el directorio de este skill. Los artefactos se guardan en .test-doctor/ (sugiere añadirlo a .gitignore).

Flujo de trabajo

1. MEDIR (script — siempre primero)

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

Detecta el ejecutor de pruebas, ejecuta la suite completa una vez como línea base de cobertura, luego vuelve a ejecutar cada archivo de prueba de forma aislada registrando líneas/ramas cubiertas y tiempo de ejecución. Escribe .test-doctor/report.json.

  • La granularidad predeterminada es por archivo de prueba (el aislamiento por prueba individual es exacto pero ejecuta cada prueba por separado; ofrece --granularity test solo para suites pequeñas o ya reducidas, o acotadas con --filter).
  • En una suite de 2000 pruebas esto lleva tiempo; ejecútalo en segundo plano e informa del progreso. Toma en serio collectionErrors en el informe: esas unidades bloquean la minimización por defecto. Si el usuario elige explícitamente --keep-unmeasured, cada unidad afectada se conserva obligatoriamente y el plan se marca como no fiable.
  • --filter crea una línea base deliberadamente acotada: la recolección, minimización y verificación cubren solo los archivos de prueba que coinciden. Indica ese alcance en cada recomendación; no es una garantía para todo el repositorio.

2. MINIMIZAR (script)

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

Selección voraz con suma ponderada: conserva repetidamente la unidad con más líneas/ramas recién cubiertas por milisegundo de ejecución hasta alcanzar el umbral de cobertura. Escribe .test-doctor/plan.json y un .test-doctor/plan.md legible con una justificación por cada unidad conservada y eliminada.

  • Pregunta al usuario sus umbrales si no los ha indicado; los valores predeterminados son umbral de líneas 0.97, sin umbral de ramas, sin límite de número de pruebas. --help lista todas las opciones.
  • Fuerza la conservación de pruebas de contrato/regresión conocidas al inicio: --keep 'contract' --keep 'regression' (expresión regular sobre el identificador de unidad).
  • Presta atención al array warnings del plan (p. ej., que el umbral no es alcanzable, o que requiere más unidades que el límite establecido). Transmíteselas al usuario textualmente.

3. REVISAR (juicio — tuyo)

Lee references/slop-patterns.md, luego revisa la lista de eliminación en plan.md:

  • Rescata cualquier prueba que verifique un comportamiento invisible para la cobertura: contratos de API públicos, regresiones que referencian un ID de issue/error, redacción de mensajes de error de los que dependen consumidores, comprobaciones de propiedades/invariantes. Vuelve a ejecutar minimize con patrones --keep adicionales en lugar de editar el plan manualmente.
  • Confirma que el resto son eliminaciones seguras; clasifícalas por patrón de slop para que el usuario vea por qué muere cada una (el archivo de patrones contiene el catálogo).

Luego revisa la lista de conservación contra references/quality-rules.md: las pruebas conservadas que huelan mal (mock-del-mock, tautologías, snapshots vacíos) se reescriben in situ — se ganan su cobertura, pero deben hacerlo limpiamente.

Solo después de esta revisión, elimina los archivos/casos de prueba de la lista de eliminación en la rama. Elimina archivos completos cuando todas sus unidades hayan sido eliminadas; edita archivos cuando solo mueran algunas pruebas dentro de ellos (granularidad de prueba).

4. REGENERAR (juicio — tuyo)

Ejecuta verify una vez (espera que pueda fallar) para obtener el informe de brechas de cobertura, luego escribe nuevas pruebas para los archivos fuente más afectados listados por verify, siguiendo references/quality-rules.md: estructura AAA, nombres basados en comportamiento, un comportamiento por prueba, mocks solo en límites externos. Prefiere una prueba sólida que cubra un comportamiento real visible por el usuario sobre tres pruebas superficiales.

5. VERIFICAR (script — cierra el ciclo)

node "$SKILL/dist/cli.mjs" verify --coverage-floor 0.97
# opcionalmente, solo para módulos críticos (lento):
node "$SKILL/dist/cli.mjs" verify --mutation --mutate "src/billing/**/*.ts" --mutation-floor 80

Vuelve a ejecutar la suite, exige que esté en verde y que la retención de líneas respecto a la línea base cumpla el umbral. Código de salida 0 = terminado; 1 = arreglar y volver a ejecutar (regenerar más pruebas o restaurar eliminaciones); 2 = problema de entorno, detenerse e informar. Las pruebas de mutación son opcionales por módulo porque son lentas; ofrécelas para los módulos que el usuario considere críticos.

La versión 2 registra la huella digital de los archivos fuente cubiertos, la configuración del ejecutor, el archivo lockfile, el ejecutor y el proveedor de cobertura. Si verify reporta desviación de procedencia, recolecta una nueva línea base. Usa --allow-provenance-drift solo con autorización explícita del usuario e informa del veredicto resultante como no fiable. Las líneas base heredadas v1 requieren igualmente la opción explícita --allow-legacy-baseline como escape.

Informar de vuelta

Resume para el usuario: unidades antes → después, retención de líneas/ramas, tiempo de ejecución antes → después, patrones de slop encontrados (con conteos), pruebas rescatadas de la lista de eliminación y por qué, pruebas regeneradas y el veredicto final de verify. Incluye la ruta a plan.md para la pista de auditoría completa.

Modos de fallo

  • Ejecutor no detectado / ambiguo → el CLI termina con código 2 y orientación; pasa --runner o --cwd (monorepos: ejecutar por paquete).
  • Recolección incompleta → arregla los fallos aislados. No los filtres solo para que el plan pase; un filtro cambia el alcance declarado de la línea base. --keep-unmeasured es el escape conservador.
  • Verify sigue fallando después de regenerar → detén el bucle tras aproximadamente 3 intentos; presenta el vacío residual archivo por archivo y deja que el usuario decida entre bajar el umbral o conservar más pruebas.
  • La suite estaba en rojo antes de empezar → no "arregles" fallos no relacionados silenciosamente; repórtalos y acuerda el alcance primero.

Skills relacionados