Tengo una anécdota relevante de algo que está sucediendo en este momento para mí. Estoy en un proyecto que no usa TDD. Nuestra gente de QA nos está moviendo en esa dirección, pero somos un equipo pequeño y ha sido un proceso largo y prolongado.
De todos modos , recientemente estaba usando una biblioteca de terceros para hacer una tarea específica. Hubo un problema con respecto al uso de esa biblioteca, por lo que se me asignó la tarea de escribir una versión de esa misma biblioteca por mi cuenta. En total, terminaron siendo aproximadamente 5,000 líneas de código ejecutable y aproximadamente 2 meses de mi tiempo. Sé que las líneas de código son una métrica pobre, pero por esta respuesta, creo que es un indicador de magnitud decente.
Necesitaba una estructura de datos particular que me permitiera hacer un seguimiento de un número arbitrario de bits. Dado que el proyecto está en Java, elegí Java BitSety lo modifiqué un poco (también necesitaba la capacidad de rastrear los 0s principales , que BitSet de Java no hace por alguna razón .....). Después de alcanzar una cobertura del ~ 93%, comencé a escribir algunas pruebas que realmente enfatizarían el sistema que había escrito. Necesitaba comparar ciertos aspectos de la funcionalidad para asegurar que serían lo suficientemente rápidos para mis requisitos finales. Como era de esperar, una de las funciones que había anulado de la BitSetinterfaz era absurdamente lenta cuando se trataba de grandes conjuntos de bits (cientos de millones de bits en este caso). Otras funciones anuladas dependían de esta función, por lo que era un enorme cuello de botella.
Lo que terminé haciendo fue ir al tablero de dibujo y encontrar una forma de manipular la estructura subyacente de BitSet, que es a long[]. Diseñé el algoritmo, les pedí a sus colegas su opinión y luego me puse a escribir el código. Luego, ejecuté las pruebas unitarias. Algunos de ellos se rompieron, y los que sí me indicaron exactamente dónde necesitaba buscar en mi algoritmo para solucionarlo. Después de corregir todos los errores de las pruebas unitarias, pude decir que la función funciona como debería. Por lo menos, podría estar tan seguro de que este nuevo algoritmo funcionó tan bien como el algoritmo anterior.
Por supuesto, esto no es a prueba de balas. Si hay un error en mi código que las pruebas unitarias no están buscando, entonces no lo sabré. Pero, por supuesto, ese mismo error podría haber estado en mi algoritmo más lento también. Sin embargo , puedo decir con un alto grado de confianza que no tengo que preocuparme por la salida incorrecta de esa función en particular. Las pruebas unitarias preexistentes me ahorraron horas, quizás días, de intentar probar el nuevo algoritmo para asegurarme de que fuera correcto.
Ese es el punto de tener pruebas unitarias independientemente de TDD, es decir, las pruebas unitarias lo harán por usted en TDD y fuera de TDD de todos modos, cuando termine refactorizando / manteniendo el código. Por supuesto, esto debe combinarse con pruebas de regresión regulares, pruebas de humo, pruebas difusas, etc., pero las pruebas unitarias , como su nombre lo indica, prueban las cosas en el nivel atómico más pequeño posible, lo que le da instrucciones sobre dónde han aparecido los errores.
En mi caso, sin las pruebas unitarias existentes, de alguna manera tendría que encontrar un método para asegurar que el algoritmo funcione todo el tiempo. Lo cual, al final ... suena mucho a pruebas unitarias , ¿no?