Lanzamos el contenedor con pruebas unitarias en Azure DevOps (VSTS)

Con la llegada de .Net Core, tenemos una gran oportunidad no solo para ejecutar nuestro código en diferentes sistemas operativos, sino también para probarlo en diferentes sistemas operativos. ¿Y qué podría ser mejor que Docker cuando se trabaja con diferentes sistemas operativos?

Las pruebas son más valiosas cuando no hay diferencia entre el entorno de prueba y los entornos de destino. Imagine que admite su aplicación en varios sistemas operativos o versiones de un sistema operativo. Con Docker, puede probar su aplicación en cada una de ellas.

En este artículo, veremos cómo crear una imagen separada en la que se lanzarán las pruebas unitarias de su aplicación y configurarla para toda esta canalización de CI / CD en VSTS que es Azure DevOps recientemente.

Si trabaja con Docker, probablemente esté utilizando compilaciones de varias etapas para construir sus contenedores. En este caso, combina la creación de archivos binarios (usando la imagen de compilación) y la creación de la imagen final (usando la imagen de tiempo de ejecución) dentro del mismo archivo Docker.

Si su sistema consta de un contenedor, en este caso el enfoque más común puede ser ejecutar pruebas como parte del proceso de construcción de la imagen final. Es decir, ejecutar pruebas en el Dockerfile.

Para hacer esto en un proceso de varios pasos, cuando ejecuta docker build ejecuta las pruebas como otro paso en la creación de la imagen final. Veamos un ejemplo simple. Digamos que tenemos dos proyectos: aplicaciones web y pruebas unitarias:


Por ahora, no nos preocupemos por lo que hace la aplicación web. Por otro lado, tenemos la única prueba que verifica el comportamiento de GuidProvider y se ve así:

 [Fact] public void Never_return_a_empty_guid() { // Arrange & Act var provider = new GuidProvider(); var id = provider.Id; // Assert Assert.NotEqual(Guid.Empty, id); } 

Ahora cree un Dockerfile que creará la imagen de la aplicación web y ejecutará las pruebas al mismo tiempo:

 FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base WORKDIR /app EXPOSE 80 FROM microsoft/dotnet:2.1-sdk AS build WORKDIR /src COPY CiCd.sln . COPY WebApplication/WebApplication.csproj WebApplication/ COPY WebApplication.Test/WebApplication.Test.csproj WebApplication.Test/ RUN dotnet restore COPY . . WORKDIR /src/WebApplication RUN dotnet build --no-restore -c Release -o /app FROM build as test WORKDIR /src/WebApplication.Test RUN dotnet test FROM build AS publish WORKDIR /src/WebApplication RUN dotnet publish --no-build -c Release -o /app FROM base AS final WORKDIR /app COPY --from=publish /app . ENTRYPOINT ["dotnet", "WebApplication.dll"] 

Este Dockerfile debe colocarse en un directorio con un archivo de solución (iCd.sln). Para crear una imagen, use el comando:

 docker build -t webapplication . 

Nuestra prueba falla (un error en GuidProvider que siempre devuelve Guid.Empty ), por lo que la construcción de la imagen fallará:

salida
 Step 15/22 : RUN dotnet test ---> Running in 423c27696356 Build started, please wait... Build completed. Test run for /src/WebApplication.Test/bin/Debug/netcoreapp2.1/WebApplication.Test.dll(.NETCoreApp,Version=v2.1) Microsoft (R) Test Execution Command Line Tool Version 15.9.0 Copyright (c) Microsoft Corporation. All rights reserved. Starting test execution, please wait... [xUnit.net 00:00:00.96] WebApplication.Test.GuidProviderTests.Never_return_a_empty_guid [FAIL] Failed WebApplication.Test.GuidProviderTests.Never_return_a_empty_guid Error Message: Assert.NotEqual() Failure Expected: Not 00000000-0000-0000-0000-000000000000 Actual: 00000000-0000-0000-0000-000000000000 Stack Trace: at WebApplication.Test.GuidProviderTests.Never_return_a_empty_guid() in /src/WebApplication.Test/GuidProviderTests.cs:line 17 Test Run Failed. Total tests: 1. Passed: 0. Failed: 1. Skipped: 0. Test execution time: 2.8166 Seconds The command '/bin/sh -c dotnet test' returned a non-zero code: 1 

Ahora veamos cómo iniciar este proceso en Azure DevOps.

Nuestra definición de compilación en este momento es una tarea de tipo Docker:



Como resultado del lanzamiento, la compilación falla porque nuestra prueba cae. Además, no tenemos resultados de la prueba (la pestaña "Prueba" está vacía), ya que la prueba no se realiza en el entendimiento de VSTS:



Ejecutar pruebas como parte de un ensamblaje de imágenes no es del todo malo, pero evitará que VSTS sepa cuál fue el resultado. Esto se debe a la "limitación" de Docker, que no permite crear volúmenes durante la docker build de Docker, por lo tanto, no podemos proporcionar un archivo con los resultados de la prueba (que puede generarse mediante la dotnet test ), este archivo permanece en un contenedor intermedio y no podemos obtenerlo fácilmente él de allí.

Tomaremos un enfoque diferente y utilizaremos una gran alternativa para docker run . Primero, levantemos un contenedor separado y ejecutemos las pruebas en él. Para ambos contenedores, podemos usar el mismo Dockerfile. En primer lugar, debemos eliminar la línea que ejecuta la dotnet test dotnet del Dockerfile, ya que ahora las ejecutaremos por separado. Ok, ahora usemos el docker run , que le permite ejecutar el Dockerfile en un punto específico. En nuestro caso, esta es la fase de prueba:

 docker build -t webapplication-tests . --target test 

El parámetro -target indica qué etapa ensamblar. Tenga en cuenta que la imagen generada se llamará " webapplication-tests ". Ahora podemos ejecutar nuestras pruebas y guardar el archivo " test-results.trx " con los resultados de su ejecución en el directorio contenedor " tests ":

 docker run -v/c/tests:/tests webapplication-tests --entrypoint "dotnet test --logger trx;LogFileName=/tests/test-results.trx" 

Aquí ejecutamos la imagen creada en el paso anterior, y a través de esto asignamos el directorio de " pruebas " del contenedor al directorio del host (en mi caso D: \ CiCD \ tests). Como resultado, obtuve resultados de pruebas en D: \ CiCD \ tests.

Para construir la imagen final, ejecute:

 docker build -t webapplication . 

La ventaja es que, gracias al modelo de nivel de Docker, no es necesario volver a realizar todos los demás pasos (es decir, no es necesario volver a compilar la aplicación).

Bueno, ahora apliquemos todo esto a las canalizaciones de Azure DevOps. Para simplificar el ensamblaje y evitar una gran cantidad de parámetros, usaremos docker-compose. Nuestro docker-compose.yml tiene el siguiente contenido:

 version: '3.5' services: webapplication: image: webapplication build: context: . dockerfile: Dockerfile webapplication-tests: image: webapplication-tests build: context: . dockerfile: Dockerfile target: test 

Aquí definimos dos imágenes (webapplication y webapplication-tests). Para que todo esté de acuerdo con el canon, agreguemos el archivo docker-compose.override.yml:

 version: '3.5' services: webapplication: environment: - ASPNETCORE_ENVIRONMENT=Development ports: - "8080:80" webapplication-tests: entrypoint: - dotnet - test - --logger - trx;LogFileName=/tests/test-results.trx volumes: - ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests/}:/tests 

Genial, ahora para ejecutar las pruebas solo necesitamos:

 docker-compose run webapplication-tests 

Este comando ejecuta las pruebas y crea el archivo trx de salida en el directorio especificado por la variable de entorno BUILD_ARTIFACTSTAGINGDIRECTORY o se BUILD_ARTIFACTSTAGINGDIRECTORY el valor predeterminado ./tests . La imagen final se hace así:

 docker-compose build webapplication 

Ahora puede editar nuestro proceso de CI en Azure DevOps. Para hacer esto, definimos los siguientes pasos:

  1. Recoge todas las imágenes [construir]
  2. Ejecutar pruebas unitarias [ejecutar]
  3. Publicar el resultado de la prueba [publicar]
  4. Ejecutar imágenes en el repositorio (Registro) [push]

Comencemos con el primer paso, que es la tarea Docker Compose (tarea) en Azure:



Ponemos Action: Build service images y especificar la ruta a docker-compose.yml.

A continuación, ejecute el contenedor con pruebas unitarias:



Aquí debe seleccionar Action: Run a specific service image y especifique el nombre del contenedor Nombre de Service Name: webapplication-tests . Además, no se olvide de la ruta a docker-compose.yml y docker-compose.override.yml. El valor de Run in Background no debe establecerse; de ​​lo contrario, el contenedor comenzará en "Modo independiente" y la tarea no esperará los resultados de las pruebas y continuará con el siguiente paso. La tarea Publicar resultados de prueba intentará publicar resultados que aún no estén disponibles, ya que ejecutar pruebas lleva tiempo.

El tercer paso es "Publicar resultados de la prueba":



Es importante especificar Run this task: Even if a previous task has failed, unless the build was canceled . Esta opción es importante porque de lo contrario los resultados nunca se publicarán si las pruebas fallan. Search folder: $(Build.ArtifactStagingDirectory)

El último paso será empujar las imágenes al almacenamiento. Para hacer esto, especifique la suscripción de Azure, así como el Registro de Contenedor de Azure. Todo está listo para crear una nueva construcción. Guardar. Empezamos Si las pruebas fallan, la compilación fallará, pero ahora vemos los resultados en VSTS:



Espero que este material haya sido útil. Puede encontrar mi archivo yml de configuración de ensamblaje aquí .

Gracias por su atencion!

Source: https://habr.com/ru/post/es430958/


All Articles