commit&push

~/blog $ git show 2026-08-25

Your Tests Run in a World That Doesn't Exist

· 6 min read · Victor Benavides

--craft--ops

Todas las pruebas en verde. Aun así, el evento me sorprendió cinco veces.

Nueve días operando el control de acceso de una feria real produjeron exactamente cero builds fallidos y cinco cosas que no había contemplado. Ninguna era un bug en el sentido habitual. Nada lanzó una excepción. Nada devolvió un 500. Ninguna aserción que yo hubiera escrito se violó jamás. La suite no estaba equivocada: estaba respondiendo una pregunta distinta a la que producción estaba haciendo.

Y esto es lo que no se me va de la cabeza. Una suite de pruebas corre en un mundo que tú construyes, y a ese mundo le falta casi todo. No tiene tiempo, ni cuerpos, ni otras personas, ni casero, ni vecinos. Es una sala limpia, y es muy buena en aquello para lo que sirven las salas limpias: demostrar que lo que ya entiendes sigue funcionando. Lo que no puede hacer es sorprenderte, porque todo lo que hay adentro lo pusiste tú.

Cinco categorías. Un caso real por cada una, todos de los mismos nueve días.

Sin cuerpos

El lector de la puerta principal se puso lento después de trece horas a batería.

Esa es toda la falla. Un dispositivo que llevaba despierto desde la mañana empezó a limitarse a sí mismo, y ninguna cantidad de ingeniería de backend tenía algo que decir al respecto.

Ningún runner de CI tiene batería. Nada en tu entorno de pruebas se calienta, se pasea por un predio ferial, se queda donde pega el sol de la tarde, ni se queda sin carga a la hora trece porque alguien lo desenchufó para cargar un celular. Tu laptop está enchufada y lleva cuarenta minutos despierta. Cada dispositivo que realmente pones en la calle vive una vida física completamente distinta, y la suite no tiene vocabulario para nada de eso.

Esta es la categoría que más fácil resulta descartar como "esto no es software en realidad". Me costó la puerta más cargada del día.

Sin tiempo

A partir de las 19:00, el tiempo medio de lectura pasó de 0.7 segundos a 2.1 segundos y se quedó ahí hasta el cierre.

Lo raro es la dirección. Esto ocurrió mientras el tráfico bajaba. La hora más cargada del día fue de las más rápidas; las horas más vacías fueron las más lentas.

19:0010:0013:0016:0022:00239 — la hora más cargada, de las más rápidas2.1s — las horas más vacías, las más lentas0.7slecturas / horatiempo medio de lectura
El primer día, graficado de dos maneras. El tráfico baja; la latencia sube y se queda arriba. Los valores etiquetados son medidos — 239 lecturas en la hora pico, alrededor de 50 por hora ya entrada la noche, una mediana que pasó de 0.7s a 2.1s — mientras que la curva entre ellos está dibujada para mostrar la forma, no para reportar cifras por hora.

Eso va al revés del modelo mental que casi todos cargamos, donde lento significa saturado. Es la firma del problema opuesto: conexiones, cachés y recursos agrupados que expiran calladamente entre pedidos, de modo que cada lectura nueva paga costos de arranque que la anterior ya había pagado.

Tu suite corre sus casos uno tras otro, en segundos, para siempre. Nada en ella está nunca ocioso, así que nada se enfría nunca. Toda una clase de comportamiento — todo lo que solo ocurre después de una pausa — es invisible por construcción. No puedes escribir la prueba "y entonces no pasó nada durante cuarenta minutos" sin que tu build demore cuarenta minutos.

Sin otras personas

Alrededor del 15% de todas las lecturas fueron rechazos, y casi todos decían lo mismo: ya está adentro.

No eran atacantes. No eran bugs. Era gente que salía por una puerta lateral a almorzar sin registrar la salida, volvía, y el sistema le decía — correctamente — que ya la tenía adentro.

La máquina de estados tenía razón. Los usuarios no la habían leído.

Las pruebas codifican el comportamiento que diseñaste. Producción ejecuta el comportamiento que la gente improvisa. Cada prueba que escribo tiene un actor bien portado adentro, porque el actor lo escribo yo, y yo ya me sé las reglas. Nadie en una feria lleva tu modelo de presencia en la cabeza. Está pensando en el almuerzo.

Sin casero

El viernes, a las 17:33, el proveedor de nube rotó los nodos debajo mío. No fue un pedido que hice ni un deploy que corrí: mantenimiento de rutina sobre infraestructura que alquilo.

Tu entorno de pruebas no tiene casero. Nada lo reinicia según el calendario de otro, nada lo migra a hardware distinto a mitad de una corrida, nada decide que el martes es buen día para mantenimiento. En las pruebas eres el único agente del universo. En producción eres inquilino, y el edificio tiene planes propios.

Sin vecinos

Todos los servicios de la plataforma tenían su suite en verde ese viernes. Catorce de ellos levantaron sin poder hablar con nada, reportando salud perfecta.

La falla no estaba dentro de ningún servicio. Vivía en el espacio entre ellos: un webhook de inyección, configurado para dejar arrancar los pods aun cuando el webhook mismo no estaba disponible, haciendo exactamente lo que se le había indicado en el peor momento posible. Ningún servicio era dueño de ese comportamiento. Las pruebas de ninguno podrían haberlo cubierto, porque desde adentro de cualquiera de ellos no había nada mal.

Las pruebas unitarias verifican una parte. Las de integración verifican una costura que ya se te ocurrió a ti. La falla vino de una costura que ninguna de las partes sabía que existía.

Para qué sirven las pruebas de verdad

Nada de esto es un argumento contra las pruebas, y quiero ser cuidadoso aquí, porque "las pruebas no lo agarraron" es una frase que se usa para justificar no escribirlas.

Mi suite ha atrapado regresiones reales y va a atrapar más. Pero una suite es un trinquete, no un telescopio. Te impide retroceder sobre comportamiento que ya entiendes. No tiene nada que decir sobre el comportamiento que todavía no imaginaste — y nunca lo va a tener, porque para escribir esa prueba primero tendrías que haberlo imaginado.

Así que la práctica a la que llegué no es más pruebas. Es esta: antes de que algo nuevo salga a producción, un humano camina el flujo completo de punta a punta, en el entorno real, en el dispositivo real, sobre la red real. No una aproximación de staging. La cosa misma. Toma una tarde y encuentra una categoría de problema que ninguna cobertura va a encontrar.

Las pruebas te dicen que no rompiste lo que entiendes. Solo la realidad te dice lo que nunca entendiste. Las dos cosas vale la pena saberlas — y solo una se puede automatizar.

$ grep -rl --tag ~/blog