Un factor importante que hace que las pruebas unitarias sean extremadamente útiles es la retroalimentación rápida .
Considere lo que sucede cuando tiene su aplicación completamente cubierta con pruebas de integración / sistema / funcional (que ya es una situación ideal, lejos de la realidad en la mayoría de las tiendas de desarrollo). Estos a menudo son dirigidos por un equipo de pruebas dedicado.
- Confirmas un cambio en el repositorio de SCM,
- en algún momento (posiblemente días) más tarde, los chicos de prueba obtienen una nueva versión interna y comienzan a probarla
- encuentran un error y presentan un informe de error,
- (en el caso ideal) alguien le asigna el informe de error.
Todo esto puede llevar días o incluso semanas. En este momento ya ha estado trabajando en otras tareas, por lo que no tiene los detalles minuciosos del código escritos anteriormente en su mente. Además, por lo general, ni siquiera tiene una prueba directa de dónde está realmente el error, por lo que lleva mucho tiempo encontrarlo y solucionarlo.
Mientras que en pruebas unitarias (TDD)
- escribes una prueba,
- escribes un código para satisfacer la prueba,
- la prueba aún falla,
- miras el código y normalmente tienes una experiencia de "¡Uy!" en unos segundos (como "¡Uy, olvidé comprobar esa condición!"), luego
- corrige el error de inmediato.
Todo esto sucede en cuestión de minutos .
Esto no quiere decir que las pruebas de integración / sistema no sean útiles; solo sirven para diferentes propósitos. Con pruebas unitarias bien escritas, puede detectar una gran proporción de los errores en el código antes de que lleguen a la fase de integración, donde ya es considerablemente más costoso encontrarlos y solucionarlos. Tiene razón en que las pruebas de integración son necesarias para detectar los tipos de errores que son difíciles o imposibles de detectar con las pruebas unitarias. Sin embargo, en mi experiencia, esos son del tipo más raro; La mayoría de los errores que he visto son causados por alguna omisión simple o incluso trivial en algún lugar dentro de un método.
Sin mencionar que las pruebas unitarias también prueban las interfaces de usabilidad / seguridad, etc., lo que le brinda comentarios de vital importancia para mejorar su diseño y API. En mi humilde opinión, puede reducir considerablemente las posibilidades de errores de integración de módulo / sistema de sistema: cuanto más fácil y limpia sea una API, menos posibilidades de malentendido u omisión.
¿Qué experiencia tiene con las pruebas unitarias automatizadas, las pruebas de integración automatizadas y las pruebas de aceptación automatizadas, y en su experiencia, qué ha producido el ROI más alto? ¿y por qué?
El ROI depende de muchos factores, probablemente el principal de ellos es si su proyecto es totalmente nuevo o heredado. Con el desarrollo greenfield, mi consejo (y experiencia hasta ahora) es hacer pruebas de unidad al estilo TDD desde el principio. Estoy seguro de que este es el método más rentable en este caso.
Sin embargo, en un proyecto heredado, construir una cobertura suficiente de pruebas unitarias es una tarea enorme que será muy lenta para obtener beneficios. Es más eficiente tratar de cubrir la funcionalidad más importante con el sistema / pruebas funcionales a través de la interfaz de usuario si es posible. (Las aplicaciones GUI de escritorio pueden ser difíciles de probar automáticamente a través de la GUI, aunque las herramientas de soporte de prueba automatizadas están mejorando gradualmente ...). Esto le proporciona una red de seguridad gruesa pero efectiva rápidamente. Luego, puede comenzar a construir gradualmente pruebas unitarias en torno a las partes más críticas de la aplicación.
Si tuviera que elegir solo una forma de prueba para automatizar en su próximo proyecto, ¿cuál sería?
Esa es una pregunta teórica y me parece inútil. Todos los tipos de pruebas tienen su uso en la caja de herramientas de un buen ingeniero de SW, y todos estos tienen escenarios en los que son insustituibles.