Pedirle a un agente "añade tests para esta función" produce tests casi siempre. El problema es que muchos de esos tests confirman que el código hace lo que hace, no que hace lo que debería hacer. Son tests que pasan el día que se escriben y no protegen de nada el día que alguien cambia el comportamiento por error.

La trampa del test que solo confirma el comportamiento actual

Un agente que ve el código y genera un test a partir de él tiende a describir lo que observa, no lo que se espera. Si la función tiene un bug, el test generado a partir del comportamiento actual puede terminar confirmando ese bug como si fuera correcto. Esto es peor que no tener test: da una falsa sensación de cobertura.

Me pasó con una función de paginación: el test que el agente generó a partir del código solo cubría la página con resultados. Cuando le pedí explícitamente el caso de lista vacía, salió a la luz que la función devolvía None en lugar de una lista vacía, un bug real que llevaba semanas en producción sin que ningún test lo hubiera tocado.

Lo que pido en su lugar

  • El comportamiento esperado, no el código, como punto de partida. Describo qué debería pasar con cada entrada relevante antes de que el agente mire la implementación, para que el test se derive de la especificación y no de lo que el código ya hace.
  • Casos límite explícitos, no solo el caso feliz. Entrada vacía, valores fuera de rango, tipos inesperados. Si no los pido explícitamente, el test generado casi siempre cubre solo el camino principal.
  • Un test que falle si quito la lógica que protege. Antes de aceptar un test, a veces le pido al agente que simule quitar la comprobación clave de la función y confirme que el test entonces falla. Si el test sigue pasando sin esa comprobación, el test no está probando lo que creo que está probando.

Por qué no dejo que el agente decida qué probar solo

Un agente optimiza, razonablemente, por generar tests que pasen con el código actual. Yo quiero tests que fallen cuando el comportamiento se rompe en el futuro, que es un objetivo distinto y a veces contrario. Por eso la especificación de qué probar la doy yo, y el agente se encarga de traducirla a código de test, no al revés.

Dónde dejo más autonomía

Para tests puramente mecánicos —serialización, formato de datos, casos de estructura— dejo que el agente proponga la cobertura completa sin que yo especifique cada caso, porque ahí el espacio de comportamientos correctos es pequeño y fácil de enumerar de forma exhaustiva de todas formas.

La recomendación

No pidas "añade tests" a secas. Describe el comportamiento esperado antes de que el agente vea la implementación, pide explícitamente los casos límite, y verifica que el test falla si quitas la lógica que se supone que protege. Un test que nunca podría fallar no es una red de seguridad, es una ilusión de cobertura.

Relacionado: Cómo reviso el código que genera un agente sin perder media hora en cada PR