Cómo ejecutar pruebas automáticamente con Claude Code Hooks: PostToolUse, Stop y verificación mínima

Guía práctica para ejecutar pruebas automáticamente con Claude Code Hooks: cuándo usar PostToolUse, cuándo usar Stop, cómo elegir comandos mínimos por tipo de archivo y cómo evitar ejecutar toda la suite tras cada cambio pequeño.

Usar Claude Code hooks para ejecutar pruebas automáticamente ayuda con un problema común: aunque hayas escrito “ejecuta pruebas después de cambiar código” en CLAUDE.md, Claude Code puede olvidarlo, ejecutar una suite demasiado grande o resumir mal un fallo.

Hooks convierte “acuérdate de hacerlo” en “ejecuta esto cuando ocurra el evento”. Para pruebas, los eventos más útiles son PostToolUse y Stop.

Resumen Rápido

Usa PostToolUse cuando quieras ejecutar una comprobación ligera justo después de que Claude edite o escriba un archivo. Limita el matcher a herramientas como Edit|Write.

Usa Stop cuando quieras una verificación final antes de que Claude termine el turno. No pongas toda la suite de pruebas ahí por defecto.

Un flujo estable suele ser:

  1. PostToolUse ejecuta comprobaciones ligeras: formato, typecheck o tests enfocados.
  2. Stop imprime una lista de verificación final o ejecuta un script estrecho.
  3. Los fallos de test devuelven un resumen, no el log completo.
  4. Los hooks del proyecto viven en .claude/settings.json; la lógica real vive en .claude/hooks/.
  5. Primero pruébalo en un proyecto pequeño.

Decide Qué Debe Ejecutarse

No empieces con:

1
npm test

Cuanto más cerca esté el comando de cada edición, más corto y determinista debería ser.

Escenario Comprobación sugerida
Cambió un componente frontend Test relacionado, typecheck, lint
Cambió una función backend Test unitario del paquete relacionado
Cambió una configuración Validación de config o build dry run
Cambió Markdown Revisión de enlaces o front matter
Termina el turno Recordatorio de verificación mínima
Antes de commit o release Suite completa y build, normalmente manual o CI

Hooks no debería reemplazar CI. Es una red local para detectar errores obvios pronto.

Estructura Recomendada

No metas lógica compleja en una sola línea dentro de settings.json.

1
2
3
4
5
6
your-repo/
  .claude/
    settings.json
    hooks/
      run-related-tests.sh
      final-check.sh

En Windows puedes usar PowerShell:

1
2
3
4
5
6
your-repo/
  .claude/
    settings.json
    hooks/
      run-related-tests.ps1
      final-check.ps1

Usar PostToolUse Después de Editar

PostToolUse se dispara después de una llamada de herramienta. Para pruebas automáticas, normalmente solo interesan las herramientas que escriben archivos.

.claude/settings.json:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/run-related-tests.sh"
          }
        ]
      }
    ]
  }
}

Esto solo registra el hook. La lógica de selección de pruebas va en el script.

Ejemplo en Bash

.claude/hooks/run-related-tests.sh:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/usr/bin/env bash
set -euo pipefail

INPUT="$(cat)"
FILE_PATH="$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // empty')"

if [ -z "$FILE_PATH" ]; then
  exit 0
fi

case "$FILE_PATH" in
  *.ts|*.tsx)
    echo "Running TypeScript checks for $FILE_PATH"
    npm run typecheck -- --pretty false
    ;;
  *.test.ts|*.spec.ts|*.test.tsx|*.spec.tsx)
    echo "Running focused test for $FILE_PATH"
    npm test -- "$FILE_PATH" --runInBand
    ;;
  *.py)
    echo "Running Python checks for $FILE_PATH"
    python -m pytest -q
    ;;
  *.md)
    echo "Markdown changed: skip code tests"
    ;;
  *)
    echo "No related test rule for $FILE_PATH"
    ;;
esac

Hazlo ejecutable:

1
chmod +x .claude/hooks/run-related-tests.sh

Ejemplo en PowerShell

.claude/hooks/run-related-tests.ps1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$inputJson = [Console]::In.ReadToEnd()
if ([string]::IsNullOrWhiteSpace($inputJson)) {
  exit 0
}

$payload = $inputJson | ConvertFrom-Json
$filePath = $payload.tool_input.file_path

if ([string]::IsNullOrWhiteSpace($filePath)) {
  exit 0
}

switch -Regex ($filePath) {
  '\.tsx?$' {
    Write-Output "Running TypeScript checks for $filePath"
    npm run typecheck -- --pretty false
    break
  }
  '\.(test|spec)\.tsx?$' {
    Write-Output "Running focused test for $filePath"
    npm test -- $filePath --runInBand
    break
  }
  '\.py$' {
    Write-Output "Running Python checks for $filePath"
    python -m pytest -q
    break
  }
  '\.md$' {
    Write-Output "Markdown changed: skip code tests"
    break
  }
  default {
    Write-Output "No related test rule for $filePath"
  }
}

Configuración:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "powershell.exe -ExecutionPolicy Bypass -File \"$CLAUDE_PROJECT_DIR/.claude/hooks/run-related-tests.ps1\""
          }
        ]
      }
    ]
  }
}

Prueba el script manualmente antes de conectarlo.

Mantén Corto el Output de Fallos

El output del hook entra en el flujo de Claude Code. Si un test falla, Claude puede usarlo para continuar. Evita logs enormes.

1
npm test -- "$FILE_PATH" --runInBand 2>&1 | tail -n 80

Los hooks deberían ejecutar comandos deterministas. Evita prompts interactivos, puertos aleatorios, servicios frágiles o confirmaciones manuales.

Usar Stop para la Revisión Final

PostToolUse sirve para comprobaciones inmediatas. Stop sirve para confirmar antes de terminar el turno.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/final-check.sh"
          }
        ]
      }
    ]
  }
}

.claude/hooks/final-check.sh:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/usr/bin/env bash
set -euo pipefail

if git diff --quiet; then
  echo "No working tree changes. Skip final checks."
  exit 0
fi

echo "Working tree changed. Suggested final checks:"
echo "- run the focused test command for touched files"
echo "- run typecheck if code changed"
echo "- run full test suite before commit or deploy"

Empieza con recordatorios y automatiza comandos caros solo cuando el flujo ya sea estable.

Cuándo No Automatizar Pruebas

Ten cuidado si:

  • los tests tardan mucho;
  • necesitan bases de datos, navegadores, colas o APIs externas;
  • modifican datos locales;
  • generan logs enormes;
  • no existe un comando mínimo estable;
  • Claude Code suele cambiar muchos archivos a la vez.

En esos casos, el hook puede sugerir el comando en lugar de ejecutarlo.

Estrategia por Riesgo

Riesgo Acción automática
Bajo formato, lint de archivo, Markdown
Medio typecheck, tests unitarios relacionados, validación de config
Alto suite completa, E2E, build, migraciones

El riesgo bajo puede ir en PostToolUse; el alto debería quedarse en CI o confirmación humana.

CLAUDE.md y Hooks

CLAUDE.md sirve para principios:

1
2
3
Después de cambios de código, prioriza la verificación mínima relacionada.
Si un test falla, corrige la causa en vez de saltarte el test.
No ejecutes E2E completo por un cambio pequeño salvo que el usuario lo pida.

Hooks sirve para ejecución:

1
2
Después de Edit o Write, ejecuta run-related-tests.sh.
En Stop, muestra sugerencias de verificación final.

Solución de Problemas

Si el hook no se ejecuta:

  1. Usa /hooks en Claude Code.
  2. Valida settings.json.
  3. Revisa nombres como PostToolUse y Stop.
  4. Revisa el matcher, por ejemplo Edit|Write.
  5. Revisa rutas de scripts.
  6. En macOS/Linux, revisa permisos de ejecución.
  7. En Windows, revisa PowerShell y comillas.
  8. Empieza con echo hook fired.
  9. No conectes tests complejos al principio.
  10. Si el output es largo, resúmelo.

Resumen

Ejecutar pruebas automáticamente con Claude Code hooks no consiste en meter npm test en una configuración. Consiste en dividir la verificación en comprobaciones pequeñas, relevantes y repetibles.

Usa PostToolUse para checks ligeros tras editar, Stop para recordatorios o verificaciones finales, y deja la suite completa para CI o confirmación humana.

记录并分享
Creado con Hugo
Tema Stack diseñado por Jimmy