Hay bastantes, pero las ventajas superan con creces las desventajas.
Hay una curva de aprendizaje empinada.
Muchos desarrolladores parecen esperar que puedan ser eficientes con la programación de prueba primero desde el primer día. Desafortunadamente, toma mucho tiempo ganar experiencia y programar a la misma velocidad que antes. No puedes evitarlo.
Para ser más específicos, es muy fácil equivocarse. Muy fácilmente (con muy buenas intenciones) puede terminar escribiendo un montón de pruebas que son difíciles de mantener o probar cosas incorrectas. Es difícil dar ejemplos aquí: este tipo de problemas simplemente requieren experiencia para resolverlos. Debe tener una buena sensación de separar las preocupaciones y diseñar para la comprobabilidad. Mi mejor consejo aquí sería hacer programación de pares con alguien que conozca TDD realmente bien.
Haces más codificación por adelantado.
Test-first significa que no puedes saltarte las pruebas (lo cual es bueno) y significa que terminarás escribiendo más código por adelantado. Esto significa más tiempo. De nuevo, no puedes evitarlo. Te recompensan con un código que es más fácil de mantener, ampliar y, en general, menos errores, pero lleva tiempo.
Puede ser una venta difícil para los gerentes.
Los administradores de software generalmente solo se preocupan por los plazos. Si cambias a la programación de prueba primero y de repente te llevas 2 semanas para completar una función en lugar de una, no les va a gustar. Definitivamente esta es una batalla que vale la pena pelear y muchos gerentes están lo suficientemente informados como para obtenerla, pero puede ser una venta difícil.
Puede ser una venta difícil para otros desarrolladores.
Dado que hay una curva de aprendizaje empinada, no a todos los desarrolladores les gusta la programación de prueba primero. De hecho, supongo que a la mayoría de los desarrolladores no les gusta al principio. Puede hacer cosas como la programación de pares para ayudarlos a ponerse al día, pero puede ser una venta difícil.
Al final, las ventajas son mayores que las desventajas, pero no ayuda si ignora las desventajas. Saber de qué se trata desde el principio le ayuda a negociar algunas, si no todas, las desventajas.
Test-first asume que está escribiendo código que es:
Si su proyecto no cumple con esos requisitos, tendrá dificultades. Los promotores de TDD no tienen buenas respuestas a esta otra para sugerirle que rediseñe su producto para encajar mejor dentro de esas líneas. Hay situaciones en las que eso es imposible o indeseable.
En la práctica, también puedo tener un gran problema con las personas que piensan que las primeras pruebas prueban realmente algo sobre la función correcta del programa. En muchos casos esto no es cierto, pero incluso en los casos en que es cierto, está lejos de ser una imagen completa de la corrección. Las personas ven cientos de pruebas aprobadas y suponen que es seguro realizar menos pruebas, ya que antes de la TDD solo hacían unos cientos de casos de prueba de todos modos. En mi experiencia, TDD significa que necesita tener aún más pruebas de integración, ya que los desarrolladores también tendrán la falsa seguridad y el dolor de cambiar todas las pruebas para hacer un gran redactor puede llevar a los desarrolladores a hacer soluciones interesantes.
Ejemplos:
Mi mejor ejemplo personal es cuando escribo código de seguridad para asp.net. Si están destinados a ejecutarse en un entorno hostil desde la configuración de la máquina, están protegidos, firmados y sellados, y debido a que se ejecutan contra objetos de Dios IIS, es muy difícil burlarse de ellos correctamente. Agregue algunas restricciones para el rendimiento y el uso de la memoria y rápidamente perderá la flexibilidad para usar objetos de marcador de posición en las áreas restantes.
Cualquier tipo de microcontrolador u otro código de entorno de bajo recurso puede no ser posible para hacer un verdadero diseño de estilo OO ya que las abstracciones no se optimizan y tiene límites de recursos bajos. Lo mismo puede decirse de las rutinas de alto rendimiento en muchos casos también.
fuente
El mayor inconveniente que he visto no es con el TDD en sí, sino con los profesionales. Adoptan un enfoque dogmático y fanático donde todo debe ser probado . A veces (muchas veces eso es), eso no es necesario. Además, podría no ser práctico (es decir, presentar una organización a TDD).
Un buen ingeniero encuentra compensaciones y aplica el equilibrio correcto de cuándo / dónde / cómo aplicar primero la prueba. Además, si se encuentra constantemente pasando mucho más tiempo desarrollando pruebas en lugar del código real (por un factor de 2-3 o más), está en problemas.
En otras palabras, sea pragmático y razonable con TDD (o cualquier cosa en el desarrollo de software para el caso).
fuente
Comencé a hacer TDD a principios de agosto de 2009 y convencí a toda mi compañía para que lo cambiara en septiembre / octubre de 2009. Actualmente, todo el equipo de desarrollo está completamente convertido, y comprometer el código no probado al repositorio se considera una mala cosa. Nos ha estado funcionando muy bien, y no puedo imaginar volver a la codificación de vaqueros.
Sin embargo, hay dos problemas que son bastante notables.
El conjunto de pruebas debe mantenerse
Cuando te tomas en serio la TDD, terminarás escribiendo muchas pruebas. Además, lleva tiempo y experiencia darse cuenta de cuál es la granularidad correcta de las pruebas (exagerar es casi tan malo como exagerar). Estas pruebas también son de código y son susceptibles a bitrot. Esto significa que debe mantenerlos como todo lo demás: actualícelo cuando actualice las bibliotecas de las que dependen, refactorice de vez en cuando ... Cuando realice grandes cambios en su código, muchas pruebas quedarán desactualizadas o incluso completamente equivocado. Si tiene suerte, simplemente puede eliminarlos, pero muchas veces terminará extrayendo los bits útiles y adaptándolos a la nueva arquitectura.
Pruebas de fuga de abstracciones de vez en cuando
Estamos utilizando Django, que tiene un marco de prueba bastante bueno. Sin embargo, a veces hace suposiciones que están ligeramente en desacuerdo con la realidad. Por ejemplo, algunos middleware pueden romper las pruebas. O, algunas pruebas hacen suposiciones sobre un backend de almacenamiento en caché. Además, si está utilizando una base de datos "real" (no SQLite3), la preparación de la base de datos para las pruebas llevará mucho tiempo. Claro, puede (y debe) usar SQLite3 y una base de datos en memoria para las pruebas que realiza localmente, pero algunos códigos se comportarán de manera diferente dependiendo de la base de datos que use. Es imprescindible configurar un servidor de integración continua que se ejecute en una configuración realista.
(Algunas personas le dirán que debe burlarse de todas las cosas, como la base de datos, o sus pruebas no son "puras", pero eso es solo ideología hablando. Si comete errores en su código de burla (y créame, lo hará), su traje de prueba será inútil.)
Dicho todo esto, los problemas que describí comienzan a notarse solo cuando está bastante avanzado con TDD ... Cuando recién está comenzando con TDD (o trabajando en proyectos más pequeños), la refactorización de pruebas no será un problema.
fuente
Para mí, hay algún problema psicológico profundo con las pruebas cada vez que intento aplicarlas ampliamente, como en TDD: si están allí, codifico descuidadamente porque confío en que las pruebas detectarán cualquier problema. Pero si no hay pruebas para proporcionar una red de seguridad, codifico cuidadosamente, y el resultado es invariablemente mejor que con las pruebas.
Tal vez solo soy yo. Pero también he leído en alguna parte que los automóviles con todo tipo de campanas y silbatos de seguridad tienden a chocar más (porque los conductores saben que las características de seguridad están ahí), por lo que tal vez sea algo para reconocer; TDD puede ser incompatible con algunas personas.
fuente
Una situación en la que la prueba primero realmente se interpone en mi camino es cuando quiero probar rápidamente alguna idea y ver si puede funcionar antes de escribir una implementación adecuada.
Mi enfoque es normalmente:
A veces no llego al paso 2.
En este caso, usar TDD ha resultado tener más desventajas que ventajas para mí:
Entonces, cuando tengo que explorar algunas ideas nuevas, no uso TDD y solo presento pruebas unitarias cuando tengo la sensación de que el nuevo código está llegando a alguna parte.
fuente
Desventajas o costos de TDD
Nota: Existe una gama de diferentes tipos de TDD. Independientemente de la unidad, BDD, ATDD u otras variantes, muchas de las dificultades persisten.
Efectos secundarios
Ya sea que se trate de burlas, accesorios o pruebas funcionales, las dependencias en estados o sistemas externos son a menudo la fuente de mayor complejidad en las pruebas, confusión en la forma de prueba y el mayor riesgo de equivocarse. Algunos problemas que he visto:
Tendrá que cambiar su enfoque de codificación, para algunos será un cambio drástico.
Diferentes personas codifican de maneras muy diferentes. En TDD, debe comenzar con una prueba que afirme un comportamiento específico y luego implementarla para que la prueba pase. He visto y era un programador cuya programación no conducía a TDD. Me tomó alrededor de 2 meses cuando comencé a acostumbrarme a cambiar mi enfoque de desarrollo.
Se necesita tiempo para comprender lo que le importa de la prueba y lo que no le importa de la prueba.
Cada equipo debe tomar una decisión explícita sobre dónde quieren trazar la línea en las pruebas. Qué cosas valoran que quieren probar y qué no. A menudo es un proceso doloroso aprender a escribir buenas pruebas, y lo que realmente te interesa de las pruebas. Mientras tanto, el código continuará en un estado de cambio hasta que haya coherencia tanto en estilo como en enfoque.
Prueba de unidad específica: grandes refactores
Un refactor grande o fundamental de una base de código significativa con decenas de miles de pruebas unitarias generará un costo enorme para actualizar todas las pruebas. Esto a menudo se manifestará en un rechazo en contra de hacer una refactorización, incluso si es lo correcto simplemente por el costo asociado con hacerlo.
fuente
Mi analogía es barreras en una pista Scalextric. Si te los pones, te vuelves mucho menos cauteloso.
Las personas también obtienen un poco de cadete de espacio con respecto a sus pruebas, ya que funcionan bien, creen que el código se ha probado completamente, mientras que solo es el comienzo del proceso de prueba.
En mi opinión, TDD es un trampolín para BDD. Una serie de pruebas que se ejecutan realmente no ayuda a los desarrolladores de soporte sin saber lo que hacen las pruebas. Con BDD, el resultado de la prueba está en inglés, que documenta las pruebas y, por lo tanto, crea una comprensión del sistema.
fuente
Los beneficios de TDD es que te obliga a proteger tu código de las personas que no lo entienden. Sí, esto a menudo te incluye a ti mismo. Pero, ¿qué sucede cuando no vale la pena guardar el código? ¡Hay un montón de código que ni siquiera debería estar allí en primer lugar! Entonces, el problema con TDD es cuando se trata de desarrolladores que escriben código incorrecto. TDD probablemente no los ayudará a escribir un buen código, es mucho más probable que escriban pruebas horribles también. Por lo tanto, en su caso, TDD solo se sumará al desorden; Las pruebas mal escritas y / o redundantes no son más divertidas que otras formas de código incorrecto.
fuente