Yeda AI Tips · #077

English

Un test que pasa contra código vacío no prueba nada

¿Tus tests seguirían pasando si borraras el código de producción? Entonces no están probando nada. Los asistentes de IA escriben tests rápido — decenas en un minuto — y una suite en verde se siente como seguridad. Pero verde solo significa "ninguna aserción falló". Un test que no puede fallar contra una implementación vacía es un test que no puede atrapar el bug que esa implementación vacía representa. Es teatro.

El problema del falso verde

La cobertura de líneas te dice qué código ejecutaron tus tests, no si notarían una falla en él. El proyecto PIT lo dice sin rodeos: "Traditional test coverage measures only which code is executed by your tests. It does not check that your tests are actually able to detect faults in the executed code." Un test puede recorrer cada rama, afirmar algo vacío como assert.ok(true) y reportar 100% de cobertura sin verificar nada.

Los tests generados por IA agravan el problema, no porque el modelo sea descuidado, sino porque optimiza para que la suite pase. Si el camino más rápido al verde es una tautología — afirmar que el mock fue llamado con el valor que el propio test configuró, o atrapar e ignorar la excepción bajo prueba — obtendrás una tautología. Pediste tests; recibiste un check verde.

La auditoría de cinco minutos

Demuestra que tus tests pueden fallar. Toma el módulo que la IA acaba de "cubrir" y rómpelo a propósito:

# 1. Gut the implementation (stub every function to return nothing)
# 2. Rerun the suite
pytest tests/test_orders.py

# Real tests: go red immediately.
# Theater: still green. Delete or rewrite them.

Reemplaza el cuerpo de la función por return None (o pass, o throw new Error()), vuelve a correr la suite y separa los tests en dos pilas. Rojo significa que el test se gana su lugar. Verde significa que nunca dependió del comportamiento. Es la versión manual del mutation testing, y toma cinco minutos por módulo.

Señales que predicen un verde falso

SíntomaLo que suele significar
assert.ok(true) / assertTrue(True)Placeholder que nunca puede fallar
El test afirma que el mock devolvió lo que se le dijo al mock que devolvieraPrueba el mock, no el código
try/catch que se traga la ruta de falloLa aserción nunca se alcanza
Snapshot actualizado cada vez que fallaEl test ratifica cambios, no los verifica
Bug corregido la semana pasada, sin nuevo test rojo-luego-verdeLa regresión puede volver en silencio

Esa última fila es el hábito más barato con el mayor retorno: cada corrección de bug se entrega con un test que falló antes del fix y pasa después. Si nunca lo viste en rojo, no sabes si funciona.

Automatízalo: mutation testing

El truco de borrar el código, industrializado. Las herramientas de mutación siembran fallas pequeñas — cambian < por <=, suman 1 a un literal, intercambian break y continue — y luego corren tu suite. Si los tests fallan, el mutante muere (killed); si pasan, sobrevive (survived), y cada sobreviviente marca un punto donde un bug real pasaría sin ser detectado.

Esto no es académico. Google integró mutation testing en su code review obligatorio: su sistema ha sido usado por ~6,000 ingenieros, mostrando mutantes sobrevivientes en los diffs que escriben y revisan.

Trucos avanzados

Recursos

Haz que los tests se ganen su verde. Este artículo acompaña al reel #077 de la serie Yeda AI Tips — tips breves y verificados contra fuentes para desarrolladores que construyen con IA.

Habla con nosotros · Más tips · Read in English