¿Debo incluir pruebas en la imagen de Docker?

19

Cuando se trata de pruebas, puedo pensar en dos opciones:

  1. Ponga tanto la prueba como la aplicación en una imagen.
  2. Incluya solo el código de la aplicación en la imagen. Cree un contenedor específico de prueba que se construya después de la imagen principal y le agregue algunas capas (código de prueba, dependencias, etc.).

Con la primera opción, puedo probar el contenedor y enviarlo exactamente como lo probé. Una desventaja obvia es que se incluirá un código innecesario (y potencialmente datos de prueba) en la imagen.

Con la segunda opción, la imagen que se envía no es exactamente la misma que la que se prueba.

Ambos parecen malas estrategias. ¿Hay una tercera estrategia mejor?

lfk
fuente
1
Básicamente te respondiste a ti mismo. Ambos son mala idea. Enviará procesos ejecutables ya probados a un contenedor de tamaño y personalizado según las necesidades. No quieres dependencias de desarrollo ni código src. En producción se considera un riesgo.
Laiv
1
La prueba antes de la contenedorización significa que el entorno no se prueba, solo el código sí. Habrás probado solo una parte de lo que estás enviando, no todo.
lfk

Respuestas:

10

Para ejecutar pruebas de tiempo de compilación, la forma preferida sería utilizar una compilación de varias etapas . Los Dockerfiles de etapas múltiples le permiten tener una etapa más grande con todas las dependencias para construir y probar, luego copiar los artefactos exactos que probó en otra etapa para obtener una imagen de tiempo de ejecución más pequeña.

También desea pruebas de nivel de sistema de múltiples contenedores, utilizando sus interfaces externas en lugar de ejecutarse dentro del contenedor. Dado que esas pruebas implican la coordinación entre servicios, requieren diferentes dependencias, como el acceso a su orquestación, no son tan exhaustivas como las pruebas de tiempo de construcción y, a menudo, están escritas en idiomas completamente diferentes, no es un gran problema ejecutarlas desde un Docker separado contenedor dedicado solo a las pruebas del sistema.

Karl Bielefeldt
fuente
1
Así que esa es más o menos la opción 2: ejecuto las pruebas en un entorno / contenedor que es muy similar a la producción, pero no exactamente lo mismo. ¿Está bien?
lfk
9

Hay una tercera forma, como dijiste tú mismo. Creo que está mezclando desarrollo, pruebas e implementación. Propongo que se considere todo el SDLC como un todo, primero, para comprender qué es lo que está tratando de lograr. Este es un gran tema, pero haré todo lo posible para resumir.

TL; DR;

En resumen, debe separar:

  • su código, de
  • la configuración de la aplicación, desde
  • La configuración del entorno del sistema.

Cada uno debe ser independiente el uno del otro y adecuadamente:

  • versión controlada
  • probado
  • desplegable

Versión más larga

Primero, tiene una aplicación compuesta de código y (conjuntos separados de) configuración. Esto debe probarse, tanto para la función de compilación como para la función intencional; esto se denomina integración continua (CI). Hay muchos proveedores de este servicio tanto en línea como localmente, por ejemplo CircleCI para un proveedor de la nube que se vincula a su repositorio y crea y prueba cada vez que se compromete. Si su repositorio es local y no puede usar un proveedor de la nube, algo como JenkinsSería un equivalente. Si su aplicación es bastante estándar, probablemente exista una imagen Docker existente que el servicio de CI pueda usar. De lo contrario, tendrá que crear uno, o un grupo de ellos, en el que pueda implementarse el código y la configuración de su aplicación. Configurado correctamente, tendrá una gran cantidad de estadísticas sobre la calidad del código de su aplicación.

Luego, una vez que esté satisfecho con la funcionalidad y la corrección de su aplicación, la base de código debe etiquetarse adecuadamente para una versión específica. Esta compilación se debe implementar en un entorno de prueba. Tenga en cuenta que el código será el mismo que el probado en su elemento de configuración (probablemente, si lo ha hecho correctamente), pero su configuración puede ser diferente. Una vez más, algunos proveedores de CI pueden ofrecer este paso para que pueda probar su implementación de una aplicación empaquetada y una configuración discreta. Esta etapa generalmente incluirá pruebas funcionales del usuario (para nuevas funcionalidades), así como pruebas automatizadas (para funcionalidades conocidas). Si la versión pasa esta etapa, tiene un candidato de versión para pruebas de integración. Puede ejecutar las pruebas de automatización desde otro contenedor Docker,algunas métricas que indican que el esfuerzo de prueba es 1: 1 al esfuerzo de codificación (aunque yo mismo no estoy seguro de esto).

Penúltimamente, el siguiente paso es donde construye su entorno (del sistema) como si fuera producción. Si está usando Docker en producción, aquí es donde pensará en el fortalecimiento de la seguridad, la optimización de la red y el servidor, etc. Sus imágenes de Docker pueden basarse en las que usó en Desarrollo (idealmente), pero puede haber cambios en la escala y la seguridad , como ya he dicho. En este momento, la prueba funcional de la aplicación debería estar completa, usted está más preocupado por la seguridad y el rendimiento. Según las pruebas funcionales, sus pruebas aquí se pueden desarrollar, implementar y ejecutar desde otras imágenes de Docker. Este paso solía ser terriblemente costoso y rara vez se hacía para hacerlo, por lo que necesitaba un hardware dedicado que reprodujera la producción. Hoy en día, esto es completamente viable, ya que puede ponerse de pie y derribar todo el entorno de casi cualquier escala bajo demanda.

Finalmente, tiene una versión que debe estar lista para producción con solo un pequeño conjunto de deltas de configuración de las pruebas de integración (direcciones IP, URI de bases de datos, contraseñas, etc.) Su base de código se ha probado al menos en tres entornos diferentes en este momento punto y la mayoría de la configuración del sistema al menos una vez.

avastmick
fuente
¿Eso significa que su CI no probará sus Dockerfiles en absoluto? Por ejemplo, si a su Dockerfile le faltara una dependencia, ¿las pruebas aún pasarían?
lfk
1
De ningún modo. Primero pruebe el código, luego pruebe la configuración de la aplicación, luego pruebe el sistema. Lo que digo es que estas son actividades discretas. Lo mejor de la contenedorización es que el sueño del desarrollo en un entorno que es igual al de la producción está muy cerca. Pero el endurecimiento dificultaría demasiado el desarrollo.
avastmick
0

Creo que estás mezclando diferentes tipos de pruebas. Básicamente, debe preguntarse: ¿Cuál es la unidad bajo prueba aquí?

El escenario más común cuando trabaja como desarrollador es escribir pruebas de unidad / integración para algún fragmento de código en el que está trabajando, donde ese fragmento de código es la unidad bajo prueba. Ejecutas esas pruebas localmente y / o en CI.

Cuando ha creado una nueva imagen acoplable, se convierte en una nueva unidad que puede probar. ¿Qué tipo de cosas te gustaría probar para esta imagen? ¿Cuál es la API que proporciona? ¿Cómo se prueba eso?

Si se trata de una aplicación web, puede iniciar un contenedor basado en la imagen y hacer algunas solicitudes HTTP y verificar que las respuestas sean lo que espera. El problema que creo que está experimentando es que está muy acostumbrado a que el marco de prueba se acople al código de la aplicación. Eso está bien durante el desarrollo, pero ahora desea probar una imagen acoplable y, por lo tanto, necesita un nuevo tipo de marco de prueba que pueda hacer eso y no esté vinculado al código de la aplicación.

Así que creo que la tercera opción que estás buscando es:

  • Ejecute sus pruebas de unidad / integración antes de construir una imagen acoplable.
  • Cree una imagen acoplable que contenga solo la aplicación que desea distribuir.
  • En lugar de agregar capas adicionales en la parte superior de la imagen de la aplicación, puede probarla tal cual la está ejecutando con algunos parámetros dados y afirmar los resultados esperados.

Entonces los pasos de CI / CD serían:

Configurar entorno de desarrollo -> Ejecutar pruebas en código -> Crear imagen final -> Ejecutar pruebas en imagen -> Implementar imagen.

Lars Nyström
fuente