Mis años de experiencia en el desarrollo de software sugieren que en la práctica no puede funcionar.
¿Lo has probado? Dave y yo escribimos el libro basado en muchos años colectivos de experiencia, tanto de nosotros mismos como de otras personas mayores en ThoughtWorks, en realidad haciendo las cosas que discutimos. Nada en el libro es especulativo. Todo lo que discutimos ha sido probado incluso en proyectos grandes y distribuidos. Pero no le sugerimos que lo tome con fe. Por supuesto, debe intentarlo usted mismo, y escriba lo que encuentre que funciona y lo que no, incluido el contexto relevante, para que otros puedan aprender de sus experiencias.
La entrega continua tiene un gran enfoque en las pruebas automatizadas. Pasamos aproximadamente 1/3 del libro hablando de ello. Hacemos esto porque la alternativa, las pruebas manuales, es costosa y propensa a errores, y en realidad no es una excelente manera de crear software de alta calidad (como dijo Deming, "Deje de depender de la inspección masiva para lograr la calidad. Mejore el proceso y cree la calidad en el producto en primer lugar ")
La cobertura completa de la prueba es imposible. Tienes que dedicar mucho tiempo, y el tiempo es dinero, para cada pequeña cosa. Esto es valioso, pero se podría pasar el tiempo contribuyendo a la calidad de otras maneras.
Por supuesto, la cobertura de prueba completa es imposible, pero ¿cuál es la alternativa: cobertura de prueba cero? Hay una compensación. En algún punto intermedio está la respuesta correcta para su proyecto. Descubrimos que, en general, debe esperar pasar aproximadamente el 50% de su tiempo creando o manteniendo pruebas automatizadas. Eso puede sonar costoso hasta que considere el costo de las pruebas manuales exhaustivas y la reparación de los errores que se presentan a los usuarios.
Algunas cosas son difíciles de probar automáticamente. Por ejemplo, GUI. Incluso Selenium no le dirá si su GUI es inestable.
Por supuesto. Echa un vistazo al cuadrante de prueba de Brian Marick. Aún necesita realizar pruebas exploratorias y pruebas de usabilidad manualmente. Pero para eso deberías usar a tus seres humanos caros y valiosos, no a las pruebas de regresión. La clave es que necesita establecer una tubería de implementación para que solo se moleste en ejecutar valiosas validaciones manuales contra las compilaciones que han pasado un conjunto integral de pruebas automatizadas. Por lo tanto, ambos reducen la cantidad de dinero que gasta en pruebas manuales y la cantidad de errores que alguna vez llegan a la prueba manual o la producción (en cuyo momento son muy costosos de solucionar). Las pruebas automatizadas realizadas correctamente son mucho más baratas durante el ciclo de vida del producto, pero, por supuesto, es un gasto de capital que se amortiza con el tiempo.
El acceso a la base de datos es difícil de probar sin accesorios voluminosos, e incluso eso no cubrirá casos extraños en su almacenamiento de datos. Del mismo modo seguridad y muchas otras cosas. Solo el código de la capa empresarial es eficazmente comprobable por unidad.
El acceso a la base de datos se prueba implícitamente mediante las pruebas de aceptación funcional basadas en escenarios de extremo a extremo. La seguridad requerirá una combinación de pruebas automáticas y manuales: pruebas de penetración automatizadas y análisis estático para encontrar (por ejemplo) desbordamientos de búfer.
Incluso en la capa empresarial, la mayoría del código no tiene funciones simples cuyos argumentos y valores de retorno puedan aislarse fácilmente para fines de prueba. Puede pasar mucho tiempo construyendo objetos simulados, que pueden no corresponder a las implementaciones reales.
Por supuesto, las pruebas automatizadas son costosas si construyes tu software y tus pruebas mal. Recomiendo consultar el libro "software orientado a objetos en crecimiento, guiado por pruebas" para comprender cómo hacerlo correctamente para que sus pruebas y código se puedan mantener con el tiempo.
Las pruebas de integración / funcionales complementan las pruebas unitarias, pero estas requieren mucho tiempo para ejecutarse porque generalmente implican reiniciar todo el sistema en cada prueba. (Si no reinicializa, el entorno de prueba es inconsistente).
Uno de los productos en los que solía trabajar tiene un conjunto de 3.500 pruebas de aceptación de extremo a extremo que tarda 18 h en ejecutarse. Lo ejecutamos en paralelo en una cuadrícula de 70 cajas y recibimos comentarios en 45m. Todavía es más largo de lo ideal, por lo que lo ejecutamos como la segunda etapa en la tubería después de que las pruebas unitarias se hayan ejecutado en unos minutos, por lo que no desperdiciamos nuestros recursos en una construcción que no tenemos un nivel básico de confianza en.
La refactorización o cualquier otro cambio rompen muchas pruebas. Pasas mucho tiempo arreglándolos. Si se trata de validar cambios de especificaciones significativos, está bien, pero a menudo las pruebas se rompen debido a detalles de implementación de bajo nivel sin sentido, no cosas que realmente brinden información importante. A menudo, los ajustes se centran en reelaborar las partes internas de la prueba, no en verificar realmente la funcionalidad que se está probando.
Si su código y sus pruebas están bien encapsulados y poco acoplados, la refactorización no interrumpirá muchas pruebas. También describimos en nuestro libro cómo hacer lo mismo para las pruebas funcionales. Si sus pruebas de aceptación se rompen, es una señal de que se está perdiendo una o más pruebas unitarias, por lo que parte del CD consiste en mejorar constantemente la cobertura de su prueba para tratar de encontrar errores más temprano en el proceso de entrega, donde las pruebas son más precisas y los errores son más baratos de arreglar.
Los informes de campo sobre errores no se pueden combinar fácilmente con la micro versión precisa del código.
Si está probando y publicando con mayor frecuencia (parte del punto del CD), es relativamente sencillo identificar el cambio que causó el error. El objetivo de CD es optimizar el ciclo de retroalimentación para que pueda identificar los errores lo antes posible después de que se registren en el control de versiones, y de hecho, preferiblemente antes de que se registren (es por eso que ejecutamos las pruebas de compilación y unidad antes del check-in).