Si vas a escribir pocas pruebas, escribí estas

Todos sabemos que habría que escribir pruebas. Casi nadie tiene el tiempo de escribir todas las que “corresponderían”, y el consejo habitual —apuntar a un porcentaje alto de cobertura— es justamente el que hace que la gente abandone, porque suena a un trabajo enorme y sin final.
Cambiemos la pregunta. Si solo pudieras escribir diez pruebas en todo el proyecto, ¿cuáles?
La respuesta es bastante clara, y casi ninguna es la que se escribe primero.
Primero: las que no sirven
Es útil sacárselas de encima, porque son las que más se escriben.
Las que prueban que el lenguaje funciona.
test('el usuario tiene nombre', () => {
const u = new Usuario({ nombre: 'Ana' });
expect(u.nombre).toBe('Ana');
});
Eso prueba que asignar una propiedad funciona. Ya lo sabemos.
Las que repiten la implementación.
test('calcula el total', () => {
expect(calcularTotal(100, 0.21)).toBe(100 * 1.21);
});
Si el código tiene el error, la prueba tiene el mismo error. Escribí el resultado
esperado como número: 121. Si no sabés cuánto tiene que dar, la prueba no está
verificando nada.
Las que prueban lo que ya garantiza el compilador. Si tu función recibe un
number, no hace falta probar qué pasa si le pasás un texto.
Las cuatro que sí
1. El error que ya te pasó
Es la de mejor relación entre esfuerzo y beneficio, y no requiere ninguna decisión: cada vez que arreglás un error, escribí una prueba que lo reproduzca antes de arreglarlo.
test('un pedido sin artículos no rompe el cálculo de envío', () => {
expect(calcularEnvio({ articulos: [] })).toBe(0);
});
Esa prueba tiene dos virtudes. Ya sabés que el caso es real, porque pasó. Y evita que vuelva, que es lo que efectivamente ocurre con los errores en el código que más se toca.
Si adoptás una sola costumbre de esta lista, que sea esta.
2. Las reglas del negocio con dinero, fechas o permisos
Son las que hacen daño de verdad cuando fallan, y las que tienen más casos límite.
test('el descuento no puede dejar el total negativo', () => {
expect(aplicarDescuento(50, 80)).toBe(0);
});
test('una suscripción vencida ayer ya no da acceso', () => {
const ayer = new Date(Date.now() - 86400000);
expect(tieneAcceso({ venceEl: ayer })).toBe(false);
});
Un error de estilo se ve. Un descuento mal calculado se factura mal durante meses hasta que alguien lo nota.
3. Una prueba que recorra el camino principal completo
Una sola, de punta a punta, del flujo que sostiene tu producto: registrarse, comprar, publicar. No de una función: de todo el camino.
test('un usuario puede comprar', async () => {
const usuario = await registrar('ana@ejemplo.com');
const carrito = await agregarAlCarrito(usuario, 'producto-1');
const pedido = await finalizarCompra(carrito, tarjetaDePrueba);
expect(pedido.estado).toBe('confirmado');
expect(await contarPedidos(usuario)).toBe(1);
});
Es más lenta y más molesta de mantener que las otras. Y es la única que detecta que dos partes que funcionan bien por separado dejaron de entenderse entre sí, que es de donde salen las fallas más caras.
Una alcanza. Si tenés dos flujos que sostienen el producto, dos.
4. Los bordes de lo que recibís de afuera
Todo lo que entra desde fuera de tu programa puede venir de cualquier forma: lo que escribe un usuario, lo que devuelve una API, lo que hay en un archivo.
test('acepta un correo con mayúsculas y espacios alrededor', () => {
expect(normalizarCorreo(' Ana@Ejemplo.COM ')).toBe('ana@ejemplo.com');
});
test('si la API no devuelve el campo precio, no rompe', () => {
expect(() => procesarProducto({ nombre: 'x' })).not.toThrow();
});
Cómo saber si una prueba vale la pena
Una sola pregunta: si esto se rompe y nadie se entera, ¿qué pasa?
- Se factura mal → escribila.
- Alguien ve datos de otro → escribila, ya.
- Un botón queda de otro color → no.
Y una segunda, para las que ya tenés: ¿esta prueba falló alguna vez por un error real? Una prueba que nunca falló, o que solo falla cuando cambiás el código a propósito, está costando mantenimiento sin dar nada.
Sobre el porcentaje de cobertura
Es la métrica más usada y la que peor mide lo que importa. Se puede tener un 90 % ejecutando todas las líneas sin verificar nada:
test('no rompe', () => {
procesarPedido(pedidoDeEjemplo); // sin un solo expect
});
Esa prueba suma cobertura y no comprueba absolutamente nada.
Diez pruebas bien elegidas valen más que doscientas automáticas. Y como beneficio secundario, diez pruebas corren en dos segundos, así que las vas a ejecutar. Doscientas tardan tres minutos y terminás ejecutándolas nunca.
Comentarios
Iniciá sesión para comentar y dar "me gusta".
Todavía no hay comentarios. Sé la primera persona en escribir uno.