¿Cómo puede funcionar la entrega continua en la práctica?

22

La entrega continua suena bien, pero mis años de experiencia en desarrollo de software sugieren que en la práctica no puede funcionar.

(Editar: para que quede claro, siempre tengo muchas pruebas ejecutándose automáticamente. Mi pregunta es acerca de cómo obtener la confianza para entregar en cada registro, que entiendo es la forma completa de CD. La alternativa no son ciclos de un año Se trata de iteraciones cada semana (que algunos podrían considerar todavía CD si se realiza correctamente), dos semanas o un mes; incluido un control de calidad antiguo al final de cada uno, que complementa las pruebas automatizadas).

  • 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.
  • Algunas cosas son difíciles de probar automáticamente. Por ejemplo, GUI. Incluso Selenium no le dirá si su GUI es inestable. 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.
  • 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.
  • 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).
  • 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.
  • Los informes de campo sobre errores no se pueden combinar fácilmente con la micro versión precisa del código.
Joshua Fox
fuente
¡Funciona muy bien para Etsy slideshare.net/OReillyOSCON/… !
YoTsumi
44
La entrega continua no requiere pruebas (pero ayuda). Se refiere al hecho de que las cosas que construye regularmente PODRÍAN ser enviadas al cliente si es necesario.
Es interesante que sus objeciones a la entrega continua se centren abrumadoramente en las pruebas como elemento del CD. Sin embargo, esa es solo una parte del rompecabezas: necesita herramientas internas competentes, desarrolladores comprometidos con inspecciones de calidad rigurosas, un enfoque de priorización más amplio en sus pruebas automatizadas, sin mencionar el fuerte apoyo de la organización. Se puede hacer, pero se necesita mucha gente para comprometerse con la causa.
Stephen Gross
1
@Stephen Sí, me estoy centrando en las pruebas, porque estoy de acuerdo con todos los demás aspectos. También estoy a favor de las pruebas. Simplemente no veo cómo puede tener suficiente confianza para implementar cada registro.
Joshua Fox
@ Thorbjørn Ravn Andersen. Ciertamente, el CD parece requerir pruebas. ¿Cómo puede tener la confianza de enviar automáticamente cada registro sin él?
Joshua Fox

Respuestas:

29

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).

Jez Humble
fuente
Gracias por tu respuesta. Sí, creo en las pruebas. Mis proyectos han tenido una buena cobertura de código de pruebas automatizadas ejecutadas con la compilación diaria. Solo digo que necesitas algún tipo de iteración antes de lanzar. "Todavía necesita realizar pruebas exploratorias ... manualmente". No entiendo. Un sistema de CD completo se implementa en cada registro. ¿Cómo puede hacer eso si incluye pruebas manuales?
Joshua Fox
3
Me gusta distinguir entre entrega continua y despliegue continuo. Aquí está la diferencia. La entrega continua significa que mantiene el sistema listo para la producción en todo momento y puede lanzar bajo demanda con solo presionar un botón. La liberación es una decisión comercial. La implementación continua es un caso limitante en el que se publican todas las compilaciones correctas (tenga en cuenta que no se registran todos los registros; algunos registros no resultan en una compilación liberable). En ambos casos, puede incluir validaciones manuales: la clave es el concepto de la canalización de implementación .
Jez Humble
En cuanto a "El acceso a la base de datos se prueba implícitamente en las pruebas de aceptación funcional basadas en escenarios de extremo a extremo". El problema clave es que esto está implícito . La gente parece contenta con eso, pero este es un enfoque que desperdicia mucho tiempo; en lugar de decir el problema "Esto es lo que esperaba del DB y obtuve esto en su lugar", dice "Algo se rompió en una de las 100 capas".
atoth
11

Primero, el CD requiere un gran ajuste mental: debes admitir que a veces las cosas se rompen sin importar lo que hagas. Al final del día, no puedes probar un resultado negativo.

Una vez que superas esto, te das cuenta de que necesitas herramientas y procedimientos para a) detectar estos errores muy rápidamente yb) revertir o implementar la actualización de manera muy eficiente. Además, si realmente está bebiendo el cóctel de CD, realmente está ofreciendo muchos cambios pequeños y puntiagudos que son fáciles de revertir y no deberían ser capaces de introducir errores importantes en toda la aplicación. Incluso los muchachos que realmente practican CD están manejando cambios importantes de una manera más tradicional.

Wyatt Barnett
fuente
"pequeños ... cambios ... no deberían ser capaces de introducir errores en toda la aplicación". Incluso en código bien factorizado, esto puede suceder. Por ejemplo, agrega un div que empuja a otro div fuera de la vista en un navegador en particular. Por ejemplo, un valor nulo aparece en un caso de esquina inesperado, arrojando una excepción y evitando que la GUI se procese en absoluto. Sí, debe probar todo lo posible, como lo hago yo, pero inevitablemente, ocurren errores y pequeños errores pueden interrumpir toda la aplicación.
Joshua Fox
Pero todavía son fáciles de encontrar y solucionar, lo cual es el mayor punto de énfasis.
Wyatt Barnett
2

Cada sistema tiene riesgos, y cada riesgo tiene costos potenciales. Si el costo de un pequeño riesgo, del tipo que puede llevar meses o años para encontrar en pruebas exhaustivas y control de calidad, es lo suficientemente alto (el software en su marcapasos cardíaco), no se envía sin un período extenso de pruebas de un liberación congelada Si el costo de la falla es lo suficientemente pequeño, tal vez envíe continuamente con cero pruebas (la página de Facebook de su gato).

hotpaw2
fuente
Sí. Para la mayoría de las aplicaciones de producción, el riesgo está en algún punto intermedio. Y me parece que el riesgo es tal que no quisiéramos implementarlo en cada registro, incluso con pruebas automatizadas. Parece que siempre se necesita una ronda de control de calidad. Pero los lanzamientos aproximadamente semanales me parecen factibles.
Joshua Fox
1

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.

No necesita una cobertura del 100%, necesita lo suficiente como para confiar en su sistema, que los cambios en un solo lugar no romperán las cosas que ya ha demostrado que funcionan.

Algunas cosas son difíciles de probar automáticamente. Por ejemplo, GUI. Incluso Selenium no le
dirá si su GUI es inestable. 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.

Sin embargo, el acceso a la base de datos es trivial para escribir. No debería necesitar muchas pruebas en su capa de datos, ya que solo está obteniendo y configurando datos. Lo más importante es asegurarse de que cuando falla, revierte y registra el problema para que pueda solucionarlo.

Del mismo modo seguridad y muchas otras cosas. Solo el código de la capa empresarial es eficazmente comprobable por unidad. 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.

Entonces, muchas de sus funciones / clases son demasiado grandes. Deben estar escritos para ser comprobables.

Puede pasar mucho tiempo construyendo objetos simulados, que pueden no corresponder a las implementaciones reales.

Sin embargo, la E / S del objeto simulado debe coincidir con lo que se espera. Lo que sucede dentro de él no es importante.

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).

Estos no deben ejecutarse todo el tiempo. Justo como sea necesario.

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.

Luego, su código está demasiado acoplado y sus pruebas están mal escritas.

Los informes de campo sobre errores no se pueden combinar fácilmente con la micro versión precisa del código.

¿No estás seguro de lo que estás haciendo aquí? Si hay un error, escriba una prueba para demostrar su existencia, luego corríjalo.

CaffGeek
fuente
"La E / S del objeto simulado debe coincidir con lo que se espera". "Construir MO que implementen por completo una especificación de interfaz lleva mucho tiempo. Peor aún, uno debe actualizarlos continuamente, de modo que uno escriba efectivamente todo el código dos veces (una vez para producción y una vez para MOs.)
Joshua Fox
1

Funciona bien para nosotros, pero nuestros clientes son principalmente internos. Múltiples compilaciones realizadas durante el día, no se toleran compilaciones rotas, se utiliza un mecanismo de inicio web para que los usuarios obtengan la última versión en cada lanzamiento. Una cosa es que el CD hace que desaparezcan muchos problemas. Sí, tiene problemas de compatibilidad todo el tiempo, sin embargo, dado que solo está implementando pequeños cambios cada vez, es muy fácil manejar los problemas. El nivel de estrés del CD es MUCHO menor que cuando realizamos grandes actualizaciones y teníamos que esperar que todo estuviera bien, ya que habría mucho código para revisar en caso de rotura.

Brian Knoblauch
fuente
-4

Para ser honesto, ¡TODO el software está en entrega continua! ¡Lo más importante es sacarlo por la puerta! Haga que sus usuarios lo usen y priorice las solicitudes de funciones y la corrección de errores después de eso.

"Buque de artistas reales"
- Steve Jobs.

Gary Willoughby
fuente
La alternativa al CD no son los ciclos de un año. Son iteraciones cada semana, dos semanas o mes.
Joshua Fox