Todo el flujo en un solo caso: cuando falla no se sabe dónde
Un test de doscientas líneas que ejercita el flujo completo y termina con quince comprobaciones. Cuando falla, el mensaje dice poco y hay que leerlo entero. Cómo partirlo sin perder cobertura.
Un solo caso de prueba que arma el escenario, ejecuta el flujo completo y hace quince comprobaciones al final. Cubre mucho y se siente completo.
Después falla en el pipeline y el mensaje dice que se esperaba true y se obtuvo false. La
pregunta “¿qué se rompió?” cuesta veinte minutos, y ese costo se paga cada vez.
Qué se pierde al juntar todo
| Consecuencia | Cómo se nota |
|---|---|
| El fallo no localiza | Hay que leer todo el test para saber en qué paso estaba |
| La primera comprobación que falla oculta el resto | Se arregla una cosa, vuelve a fallar, se arregla otra: tres vueltas de pipeline |
| El nombre no dice nada | «funciona el checkout» no aporta información cuando aparece en rojo |
| Se vuelve frágil | Cualquier cambio en cualquiera de los pasos lo rompe, aunque no toque lo que verifica |
Y hay un efecto cultural: un test largo que falla seguido por motivos ajenos es el primer candidato a que alguien lo marque como omitido “por ahora”. Un test omitido es peor que no tenerlo, porque figura en la lista y da tranquilidad falsa.
Cómo se parte
Partir no significa repetir el escenario quince veces. Significa separar la preparación de las verificaciones.
La estructura que funciona
- Un escenario compartido, armado en la preparación del grupo: los datos, el estado inicial, la ejecución del flujo.
- Un caso por comportamiento verificado. Cada uno con una o dos comprobaciones y un nombre que describa la regla: «no permite avanzar sin medio de pago», «descuenta el cupón una sola vez».
- Nombres que se lean en el reporte. El nombre del test es el mensaje de error que uno va a ver; si dice la regla, muchas veces no hace falta abrir el archivo.
- Sin dependencias entre casos. Que el orden de ejecución no importe: un test que necesita que otro haya corrido antes es un test que va a fallar solo cuando se ejecuten en paralelo.
La preparación que se vuelve el problema
Cuando el escenario necesita treinta líneas para existir, el test es difícil de leer y el diseño está avisando algo.
Antes de seguir, predecí
Y si la preparación es enorme porque el componente necesita medio sistema para funcionar, eso no es un problema del test: es acoplamiento. El test lo está reportando.
Qué nivel de test corresponde
Parte de estos casos gigantes existen porque se usó un test de extremo a extremo para verificar algo que era lógica pura.
La regla práctica
- Lógica de negocio: test unitario, rápido, sin dependencias. Ahí van todos los casos de borde.
- Integración entre piezas propias: unos pocos, verificando que el contrato se respeta.
- Extremo a extremo: los caminos críticos y nada más. Son lentos, frágiles y caros de mantener; su valor es confirmar que el sistema está enchufado, no cubrir combinaciones.
Más a fondo · nivel seniorEl test largo que sí vale la pena
Hay una excepción legítima: el test que documenta un flujo completo de negocio, escrito como narrativa, para que alguien entienda cómo se usa el sistema. Ése puede ser largo, y lo que lo hace aceptable es que sea uno solo, explícitamente pensado como documentación, y que la cobertura real de los casos esté en los tests chicos. El problema no es la longitud: es que un test largo sea el único lugar donde se verifica una regla.
El test grande contra los chicos
Código bajo prueba
const orderTotal = (items, coupon, shipping) => {
const subtotal = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
const discount = coupon ? subtotal * coupon.rate : 0;
const shippingCost = subtotal - discount > 5000 ? 0 : shipping;
return subtotal - discount + shippingCost;
};Metele un bug
El código está como lo escribió quien lo programó: toda la suite pasa.
La suite
- pasacalcula el total de un pedido completo15 comprobaciones sobre subtotal, descuento, envío y total
- pasael subtotal suma precio por cantidadorderTotal([{price: 100, quantity: 2}], null, 0) === 200
- pasael cupón descuenta su porcentajeorderTotal([{price: 100, quantity: 1}], {rate: 0.1}, 0) === 90
- pasaarriba de 5000 el envío es gratisorderTotal([{price: 6000, quantity: 1}], null, 800) === 6000
Cuántos tests y de qué tipo
Cierre
Autoevaluación
¿Lo entendiste?
Práctica