CoffeeTest
PodcastBlogContraseñaDonar
CoffeeTestLet's talk about QA and code. Join us cup by cup.
    Desarrollo

    TDD en la vida real: por qué falla y cómo rescatarlo

    CoffeeTest Team
    18 de abril de 2026

    ⏱️ Tiempo de lectura: 7 minutos

    TDD en la vida real: por qué falla y cómo rescatarlo

    Era un martes cualquiera. Teníamos un sprint con fecha límite el viernes, el PM respirando en el cuello, y un compañero que propuso con toda la ilusión del mundo: "¿Y si hacemos TDD?". Tres días después, el código tenía más tests que lógica real, nadie entendía qué probaba qué, y terminamos borrando la mitad para poder entregar algo. Clásico.

    TDD —Test Driven Development— es una de esas prácticas que todo dev conoce, muchos dicen aplicar, y poquísimos realmente sostienen más allá de un tutorial. No porque sea mala idea. Es porque entre el concepto y la ejecución hay un abismo que los libros no te cuentan.

    Este artículo no es un manual de TDD. Es una conversación honesta sobre por qué falla, cuándo sí tiene sentido, y qué ajustes concretos han marcado la diferencia en proyectos reales.


    El ciclo Red-Green-Refactor no es el problema

    Si no lo conoces: la idea de TDD es escribir primero el test que falla (red), luego el código mínimo para que pase (green), y después limpiar sin romper nada (refactor). Simple en papel.

    El problema no es el ciclo. El problema es que la mayoría lo interpreta como "escribe todos los tests antes de tocar el código", y eso en un feature complejo con requisitos ambiguos es una receta para el caos.

    En mi experiencia, cuando el equipo empieza a escribir tests para funcionalidades que ni siquiera entiende bien todavía, lo que ocurre es preocupante: los tests terminan acoplados a la implementación, no al comportamiento. Y ahí viene el verdadero dolor.

    Tests que prueban el cómo, no el qué

    Este es el error más común que veo. Un test que verifica que se llamó a un método interno tres veces con ciertos parámetros no está probando que tu feature funciona; está probando que escribiste el código de una forma específica. Cualquier refactorización legítima rompe ese test, aunque el comportamiento externo siga siendo correcto.

    Ojo que esto no es un problema de TDD en sí —es un problema de qué decides testear. Pero TDD mal aplicado te empuja directamente hacia ese antipatrón, porque escribes el test mirando la implementación que ya tienes en mente.


    Cuándo TDD realmente brilla

    Hay contextos donde TDD no solo funciona: es claramente superior a cualquier otra aproximación.

    Lógica de negocio pura

    Si estás implementando reglas de negocio —cálculo de descuentos, validaciones complejas, transformaciones de datos— TDD es oro. El comportamiento esperado es claro, los casos edge son predecibles, y cada test que escribes antes te fuerza a pensar en el contrato de tu función antes de en su implementación.

    Algo que me ha funcionado mucho: cuando hay una regla de negocio que el PM me explica en lenguaje natural, la traduzco directamente a un test antes de abrir el editor. "Si el usuario tiene más de 3 órdenes fallidas en 24 horas, bloquear la cuenta" → eso es un test en tres líneas. El código viene después, casi solo.

    Corrección de bugs

    Este es el uso de TDD que más convence a los escépticos. Cuando llegas a un bug en producción, lo primero que haces es escribir un test que lo reproduce. Ese test falla (red). Arreglas el bug. El test pasa (green). Y ahora tienes garantía de que ese bug específico no va a volver jamás sin que te enteres.

    No hay debate filosófico aquí. Es puro pragmatismo. Y funciona siempre.

    Refactorizaciones grandes

    Si vas a reescribir un módulo legacy, tener una suite de tests escrita antes de tocar una sola línea de producción es lo que separa una refactorización exitosa de un desastre. Aquí no es TDD puro en el sentido estricto, pero el espíritu es el mismo: define el comportamiento esperado antes de cambiar la implementación.


    Por qué los equipos abandonan TDD a las dos semanas

    Lo he visto demasiadas veces. El equipo se entusiasma, hace el onboarding, y en dos semanas el número de tests nuevos cae en picada. ¿Qué pasa?

    Los tests tardan demasiado en correr. Si tu suite completa tarda 8 minutos, nadie la va a correr en cada cambio. El feedback loop se rompe y TDD pierde todo su valor. La solución no es resignarse: es arquitectura. Tests unitarios rápidos (milisegundos), tests de integración separados, y CI que corre todo en paralelo.

    No hay acuerdo en qué merece un test. ¿Testeas los getters? ¿Los constructores? ¿Las funciones de utilidad triviales? Sin un criterio compartido, el equipo pierde tiempo en debates o, peor, escribe tests de relleno que dan falsa confianza.

    Ahora bien, el criterio que yo uso es simple: si este código fallara en producción y yo no me enterara hasta que un usuario se quejara, merece un test. Si el error sería obvio de inmediato, probablemente no.

    Mocking sin control. El mocking es una herramienta, no una filosofía. Cuando ves tests con 15 líneas de setup de mocks para probar una función de 5 líneas, algo salió mal en el diseño. Los tests difíciles de escribir son síntomas de código difícil de mantener. Escúchalos.


    Una aproximación que funciona en equipos reales

    Después de varios proyectos, lo que más me ha funcionado no es TDD al 100% ni ignorarlo completamente. Es algo más pragmático:

    Test-first para lógica de negocio y bugs. Siempre. Sin excepción.

    Test-after para código exploratorio. Cuando estás prototipando o entendiendo un dominio nuevo, escribir el test primero puede ser contraproducente. Explora, entiende, y luego vuelve y escribe los tests que capturen el comportamiento que descubriste.

    Cobertura como métrica secundaria, no primaria. El 80% de cobertura con tests que prueban comportamiento real vale infinitamente más que el 100% con tests que solo incrementan el número. Tu pipeline de CI no debería romperse por falta de cobertura en código trivial.

    Tests como documentación. Si alguien nuevo en el equipo no puede entender qué hace un módulo leyendo sus tests, los tests están mal escritos. Los nombres de los tests son documentación ejecutable. Trátales como tal.


    El punto real de TDD

    TDD no es sobre tener muchos tests. Es sobre diseñar mejor código a través de la presión que ejercen los tests. Un test difícil de escribir es una señal de que tu diseño tiene problemas de acoplamiento o de responsabilidades mezcladas.

    La pregunta no es "¿hacemos TDD o no?". La pregunta es "¿estamos usando los tests para pensar mejor, o solo para cumplir una métrica?".

    Dicho esto: si nunca has probado TDD en un contexto real más allá de un tutorial, elige un módulo pequeño con lógica de negocio clara y pruébalo durante una semana. No el proyecto entero. Un módulo. La diferencia en cómo piensas el diseño va a ser notable.

    ¿Tu equipo usa TDD? ¿Qué ha funcionado y qué ha sido un desastre? Me interesa saberlo — los comentarios son el lugar menos corporativo de internet.

    #TDD
    #testing
    #unit testing
    #desarrollo de software
    #automatización
    #buenas prácticas
    #QA

    💬 Comentarios