Saltar al contenido
Curso Claude Code
35/57 Hooks Lanzar los tests de Pest con un hook de Claude Code
Tu lectura Quedan 19 min
Lección 35 de 57 · Hooks

Lanzar los tests de Pest con un hook de Claude Code

19 min de lectura Claude Code 2.1.283

Hola, bienvenido. En la lección anterior creamos los hooks de Pint y PHPStan y la acción CompleteTask, y en esta lección cerramos la sección de hooks con los 2 que nos faltan. El primero es test.sh, que lanza la suite de Pest en segundo plano después de cada edición de un archivo PHP, sin que Claude tenga que esperar a que termine, y veremos también asyncRewake, una alternativa que despierta a Claude en cuanto algo falla. El segundo es context-check.sh, que se ejecuta en UserPromptSubmit y te avisa cuando la sesión ya es muy larga. Por el camino veremos cómo comprobar lo que devuelven estos hooks, que es menos evidente de lo que parece, y para probarlo todo le pediremos a Claude el test de la acción que creamos en la lección anterior.

¿Por qué un hook para los tests, si CLAUDE.md ya le pide a Claude que lance composer qa al terminar? Por el mismo motivo que los hooks de calidad: el circuito completo llega al final, y un test que se rompe a mitad de una tarea es mucho más fácil de arreglar en el momento que 5 archivos después. La diferencia con Pint y PHPStan es el tiempo. Formatear o analizar un archivo tarda un par de segundos, pero la suite de tests crece con el proyecto, y un hook normal bloquea a Claude hasta que termina. Por eso este hook va a ser asíncrono.

Tests en segundo plano con async

Un hook de tipo command con "async": true se ejecuta en segundo plano: Claude Code lo arranca y sigue trabajando sin esperarlo. Cuando el script termina, Claude Code le entrega a Claude su additionalContext en el siguiente turno de la conversación, y si en ese momento la sesión está parada, el resultado espera a tu siguiente mensaje. Eso tiene 4 consecuencias que tenemos que conocer antes de escribir el script:

  • No puede bloquear nada. Cuando termina, la acción que habría podido controlar ya ha ocurrido, así que campos como decision o continue no tienen efecto. Para un hook que informa, como el nuestro, no es un problema.
  • No tiene tiempo máximo. Claude Code no le aplica el timeout a un hook asíncrono que ya se está ejecutando, así que no tiene sentido ponérselo.
  • No se deduplica. Cada disparo crea un proceso independiente, así que si Claude edita 4 archivos seguidos, lanza 4 suites. Esto nos va a obligar a añadir algo al script, como veremos enseguida.
  • Sus avisos no se ven. Los avisos de que un hook asíncrono ha terminado están ocultos por defecto. Se ven en modo verbose, que activas con Ctrl+O o arrancando Claude Code con claude --verbose.

Y una más para cuando lleguemos a los scripts: en modo no interactivo, con claude -p, Claude Code mata al terminar los hooks asíncronos que sigan en marcha, así que este hook está pensado para las sesiones interactivas.

Para seguir esta lección necesitas claude-tasks con los commits de la lección anterior, incluida la acción app/Actions/CompleteTask.php, los contenedores de Sail levantados y jq instalado. Todo lo que vamos a usar está disponible en la versión 2.1.283, con la que está escrito el curso.

Lo que queda de esta lección
  1. 02El hook de los tests
  2. 03asyncRewake como alternativa
  3. 04El hook del contexto
  4. 05Registrarlos en settings.json
  5. 06Cómo ver lo que devuelven
  6. 07La prueba: el test de CompleteTask
Sigue leyendo con tu suscripción El curso completo, con el certificado y el foro con los planes trimestral y anual, está incluido en la suscripción. Ver los planes