Saltar al contenido principal
Volver a todos los artículos
Desarrollo Práctico5 min de lectura

Testing en el Mundo Real: Lo que Pruebo y lo que Ignoro para Lanzar Más Rápido

Una guía pragmática sobre cómo enfocar tus esfuerzos de testing para maximizar la velocidad de desarrollo sin sacrificar la calidad. Descubre qué pruebas aportan valor real y cuáles son una pérdida de tiempo.

Llevo años en esto. He montado productos desde cero, he trabajado en equipos grandes y he visto proyectos ahogarse en su propia complejidad. Una de las áreas donde más se pierde el tiempo y la energía es, sin duda, el testing.

Al principio, eres un idealista. Lees sobre la pirámide de testing, TDD, BDD y te propones alcanzar el Nirvana del 100% de cobertura. Luego, la realidad te golpea. El mercado no espera. Tu runway se acorta. Y te das cuenta de que pasar una semana testeando cada getter y setter no te ayuda a conseguir tu próximo cliente.

El objetivo del testing no es tener una suite de pruebas perfecta, es tener confianza para desplegar. Es una herramienta de gestión de riesgos, no un dogma. Así que, con el tiempo, he desarrollado un enfoque mucho más pragmático. Esto es lo que pruebo de verdad y lo que he aprendido a ignorar.

Lo que SÍ pruebo, sin excepción

Estas son las áreas no negociables. Si algo de esto falla, el producto está roto, pierdo dinero o la confianza de mis usuarios. Son mi red de seguridad.

1. Los Flujos Críticos de Negocio (Happy Paths): El camino que recorre un usuario para darte dinero o para obtener el valor principal de tu producto. En un e-commerce, sería el flujo completo: buscar un producto, añadirlo al carrito, iniciar sesión, pagar y recibir la confirmación. Pruebo esto de principio a fin. Me da igual si el botón es azul o verde, lo que necesito saber es si el usuario puede completar la compra. Estos suelen ser un puñado de tests de integración o E2E (End-to-End).

2. Lógica de Negocio Compleja y Aislada: Cualquier pieza de código que contenga reglas de negocio importantes y que no dependa de frameworks o I/O. Piensa en cálculos de precios, algoritmos de matching, lógica de permisos, o la gestión de estados de un pedido. Estas funciones suelen ser "puras" (reciben datos, devuelven datos) y son fáciles y rápidas de probar con tests unitarios. Aquí es donde se esconden los bugs más sutiles y costosos.

3. Contratos con APIs Externas: Mi aplicación depende de Stripe para los pagos, de SendGrid para los emails y de Google Maps para la geolocalización. No pruebo la API de Stripe, pero sí pruebo mi integración con ella. Verifico que la estructura de datos que envío es la correcta y que sé cómo manejar las respuestas esperadas (y los errores comunes). Suelo usar "contract testing" o tests de integración que se ejecutan con menos frecuencia para asegurar que el contrato no ha cambiado.

4. Seguridad y Autorización: ¿Puede un usuario `A` ver o modificar los datos del usuario `B`? Esta es la pesadilla de cualquier fundador. Pruebo de forma exhaustiva que mis políticas de acceso funcionan. Un test que intente acceder a un recurso sin permisos es mil veces más valioso que 20 tests de UI.

Lo que he dejado de probar (o pruebo mucho menos)

Aquí es donde me volví pragmático. Dejar de hacer esto me ha ahorrado cientos de horas.

1. Operaciones CRUD Triviales: ¿Pruebo si mi ORM (como ActiveRecord, Django ORM o Prisma) puede crear, leer, actualizar o borrar un registro simple? No. Confío en el framework. Si mi controlador lo único que hace es llamar a `User.create(params)`, no escribo un test para ello. Es ruido. Solo testeo si hay lógica adicional en el proceso (por ejemplo, si al crear un usuario se debe enviar un email de bienvenida).

2. Getters y Setters Simples: Si una función solo devuelve o establece el valor de una propiedad sin ninguna lógica, no la testeo. Mi editor de código ya me dice si hay un error de sintaxis. Es puro relleno para inflar la cobertura.

3. Cada Detalle de la Interfaz de Usuario (UI): Antes me obsesionaba con tests que comprobaban si un `div` contenía el texto exacto "Bienvenido a mi App" o si un botón tenía la clase `btn-primary`. Estos tests son increíblemente frágiles; un pequeño cambio de marketing y se rompen todos. Ahora, mis tests de UI son tests de flujo (`¿puedo hacer login?`) y dejo la validación visual de componentes a herramientas como Storybook y a la revisión manual. La automatización visual es cara y, para la mayoría de los productos, no compensa.

4. El Código de Librerías Externas: No escribo tests para ver si `axios` hace peticiones HTTP correctamente o si `date-fns` formatea bien una fecha. Millones de desarrolladores ya confían en ellas. Yo solo pruebo que *mi código* las usa como espero.

Conclusión: Busca confianza, no perfección

Mi "pirámide de testing" hoy se parece más a un diamante. Una base sólida de tests unitarios solo para la lógica de negocio crítica, una capa muy ancha y valiosa de tests de integración que prueban cómo colaboran mis módulos, y una punta muy fina de tests E2E para los flujos más importantes.

El objetivo es simple: tener la máxima confianza con el mínimo esfuerzo. Cada test que escribes tiene un coste de mantenimiento. Sé implacable a la hora de decidir si ese coste te devuelve un valor real. No dejes que la búsqueda del 100% de cobertura te impida lanzar tu producto.

Escrito por Samuel Moreno

Socio y Desarrollador en Sinergia Barcelona.