Ejercicio: Ejecución de pruebas de carga en Azure Pipelines

Completado

En esta sección, ejecutarás el plan de pruebas que creaste en el pipeline de lanzamiento. El plan de prueba usa Apache JMeter para ejecutar pruebas de carga.

Aquí se muestra cómo ejecutar las pruebas:

  • Capture y consulte una rama de Git que implemente las pruebas.
  • Modifique la canalización para instalar JMeter, ejecute el plan de prueba, transforme los resultados en JUnit y publique los resultados en Azure Pipelines.
  • Inserte la rama en GitHub, vea las pruebas que se ejecutan en Azure Pipelines y, a continuación, examine los resultados.

Captura de la rama de GitHub

En esta sección, capturaremos la rama jmeter de GitHub y la extraeremos del repositorio, o cambiaremos a ella.

Esta rama contiene el proyecto Space Game con el que ha trabajado en módulos anteriores. También contiene una configuración de Azure Pipelines con la que empezar.

  1. En Visual Studio Code, abra el terminal integrado.

  2. Ejecute los comandos jmeter y git fetch siguientes para descargar una rama denominada git checkout desde el repositorio de Microsoft y cambie a esa rama:

    git fetch upstream jmeter
    git checkout -B jmeter upstream/jmeter
    

    Recuerde que upstream hace referencia al repositorio de GitHub de Microsoft. La configuración de Git del proyecto conoce el repositorio remoto ascendente porque hemos configurado esa relación al bifurcar el proyecto desde el repositorio de Microsoft y clonarlo localmente.

    En resumen, va a insertar esta rama en el repositorio de GitHub, conocido como origin.

  3. Opcionalmente, en Visual Studio Code, abra el archivo azure-pipelines.yml . Revise la configuración inicial.

    La configuración es similar a las que creó en módulos anteriores en esta ruta de aprendizaje. Solo compila la configuración de liberación de la aplicación. Por motivos de brevedad, omite los desencadenadores, las aprobaciones manuales y las pruebas que ha configurado en módulos anteriores.

    Nota:

    Una configuración más sólida podría especificar las ramas que participan en el proceso de compilación. Por ejemplo, para facilitar la comprobación de la calidad del código, podríamos ejecutar pruebas unitarias cada vez que insertemos un cambio en cualquier rama. También podríamos implementar la aplicación en un entorno que realice pruebas más exhaustivas. Pero esta implementación solo se realiza cuando se tiene una solicitud de cambios, cuando se tiene una versión candidata para lanzamiento o cuando se combina código en la rama principal.

    Para más información, consulte Implementar un flujo de trabajo de código en la canalización de compilación mediante Git y GitHub y Desencadenadores de la canalización de compilación.

  4. Opcionalmente, en Visual Studio Code, puede consultar el archivo de plan de prueba de JMeter, LoadTest.jmx y la transformación XLST, JMeter2JUnit.xsl. El archivo XLST transforma la salida de JMeter en JUnit para que Azure Pipelines pueda visualizar los resultados.

Adición de variables a Azure Pipelines

El plan de pruebas original del equipo proporciona un valor codificado de forma rígida para el nombre de host del sitio web Space Game que se ejecuta en el entorno de almacenamiento provisional.

Para que el plan de prueba sea más flexible, tu versión usa una propiedad JMeter. Piense en una propiedad como una variable que se puede establecer desde la línea de comandos.

Aquí se muestra cómo se define la hostname variable en JMeter:

Captura de pantalla de la configuración de la variable hostname en Apache JMeter.

Aquí se muestra cómo la hostname variable usa la función __P para leer la hostname variable.

Captura de pantalla para leer la variable hostname en Apache JMeter.

El archivo de plan de prueba correspondiente, LoadTest.jmx, especifica esta variable y la usa para establecer el nombre de host.

Al ejecutar JMeter desde la línea de comandos, se usa el -J argumento para establecer la hostname propiedad . Este es un ejemplo:

apache-jmeter-5.4.3/bin/./jmeter -n -t LoadTest.jmx -o Results.xml -Jhostname=tailspin-space-game-web-staging-1234.azurewebsites.net

Aquí, establecerá la variable STAGING_HOSTNAME en Azure Pipelines. Esta variable apunta al nombre de host del sitio que se ejecuta en App Service en el entorno de almacenamiento provisional. También configuras el jmeterVersion para especificar la versión de JMeter que se va a instalar.

Cuando se ejecuta el agente, estas variables se exportan automáticamente al agente como variables de entorno, por lo que la configuración de la canalización puede ejecutar JMeter de esta manera:

apache-jmeter-5.4.3/bin/./jmeter -n -t LoadTest.jmx -o Results.xml -Jhostname=$(STAGING_HOSTNAME)

Vamos a agregar las variables de canalización ahora, antes de actualizar la configuración de la canalización. Para ello:

  1. En Azure DevOps, vaya al proyecto Space Game - web - Pruebas no funcionales .

  2. En Canalizaciones, seleccione Biblioteca.

  3. Seleccione el grupo de variables de liberación .

  4. En Variables, seleccione + Agregar.

  5. En el nombre de la variable, escriba STAGING_HOSTNAME. Como valor, escriba la dirección URL de la instancia de App Service que corresponde al entorno de almacenamiento provisional, como tailspin-space-game-web-staging-1234.azurewebsites.net.

    Importante

    No incluya el prefijo de protocolo http:// o https:// en su valor. JMeter proporciona el protocolo cuando se ejecutan las pruebas.

  6. Agregue una segunda variable denominada jmeterVersion. Para su valor, especifique 5.4.3.

    Nota:

    Esta es la versión de JMeter que usamos por última vez para probar este módulo. Para obtener la versión más reciente, consulte Descarga de Apache JMeter.

  7. Para guardar la variable en la canalización, seleccione Guardar cerca de la parte superior de la página.

    El grupo de variables es similar al que se muestra en la imagen siguiente:

    Captura de pantalla de Azure Pipelines, en la que se muestra el grupo de variables. El grupo contiene cinco variables.

Modificación de la configuración de canalización

En esta sección, modificará la canalización para ejecutar las pruebas de carga durante la fase de almacenamiento provisional.

  1. En Visual Studio Code, abra el archivo azure-pipelines.yml . A continuación, modifique el archivo de la siguiente manera:

    Sugerencia

    Puede reemplazar todo el archivo o simplemente actualizar el elemento resaltado.

    trigger:
    - '*'
    
    variables:
      buildConfiguration: 'Release'
    
    stages:
    - stage: 'Build'
      displayName: 'Build the web application'
      jobs:
      - job: 'Build'
        displayName: 'Build job'
        pool:
          vmImage: 'ubuntu-20.04'
          demands:
          - npm
    
        variables:
          wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot'
          dotnetSdkVersion: '6.x'
    
        steps:
        - task: UseDotNet@2
          displayName: 'Use .NET SDK $(dotnetSdkVersion)'
          inputs:
            version: '$(dotnetSdkVersion)'
    
        - task: Npm@1
          displayName: 'Run npm install'
          inputs:
            verbose: false
    
        - script: './node_modules/.bin/node-sass $(wwwrootDir) --output $(wwwrootDir)'
          displayName: 'Compile Sass assets'
    
        - task: gulp@1
          displayName: 'Run gulp tasks'
    
        - script: 'echo "$(Build.DefinitionName), $(Build.BuildId), $(Build.BuildNumber)" > buildinfo.txt'
          displayName: 'Write build info'
          workingDirectory: $(wwwrootDir)
    
        - task: DotNetCoreCLI@2
          displayName: 'Restore project dependencies'
          inputs:
            command: 'restore'
            projects: '**/*.csproj'
    
        - task: DotNetCoreCLI@2
          displayName: 'Build the project - $(buildConfiguration)'
          inputs:
            command: 'build'
            arguments: '--no-restore --configuration $(buildConfiguration)'
            projects: '**/*.csproj'
    
        - task: DotNetCoreCLI@2
          displayName: 'Publish the project - $(buildConfiguration)'
          inputs:
            command: 'publish'
            projects: '**/*.csproj'
            publishWebProjects: false
            arguments: '--no-build --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)'
            zipAfterPublish: true
    
        - publish: '$(Build.ArtifactStagingDirectory)'
          artifact: drop
    
    - stage: 'Dev'
      displayName: 'Deploy to the dev environment'
      dependsOn: Build
      jobs:
      - deployment: Deploy
        pool:
          vmImage: 'ubuntu-20.04'
        environment: dev
        variables:
        - group: Release
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: drop
              - task: AzureWebApp@1
                displayName: 'Azure App Service Deploy: website'
                inputs:
                  azureSubscription: 'Resource Manager - Tailspin - Space Game'
                  appName: '$(WebAppNameDev)'
                  package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/*.zip'
    
    - stage: 'Test'
      displayName: 'Deploy to the test environment'
      dependsOn: Dev
      jobs:
      - deployment: Deploy
        pool:
          vmImage: 'ubuntu-20.04'
        environment: test
        variables:
        - group: 'Release'
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: drop
              - task: AzureWebApp@1
                displayName: 'Azure App Service Deploy: website'
                inputs:
                  azureSubscription: 'Resource Manager - Tailspin - Space Game'
                  appName: '$(WebAppNameTest)'
                  package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/*.zip'
    
    - stage: 'Staging'
      displayName: 'Deploy to the staging environment'
      dependsOn: Test
      jobs:
      - deployment: Deploy
        pool:
          vmImage: 'ubuntu-20.04'
        environment: staging
        variables:
        - group: 'Release'
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: drop
              - task: AzureWebApp@1
                displayName: 'Azure App Service Deploy: website'
                inputs:
                  azureSubscription: 'Resource Manager - Tailspin - Space Game'
                  appName: '$(WebAppNameStaging)'
                  package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/*.zip'
      - job: RunLoadTests
        dependsOn: Deploy
        displayName: 'Run load tests'
        pool:
          vmImage: 'ubuntu-20.04'
        variables:
        - group: Release
        steps:
        - script: |
            wget -c archive.apache.org/dist/jmeter/binaries/apache-jmeter-$(jmeterVersion).tgz
            tar -xzf apache-jmeter-$(jmeterVersion).tgz
          displayName: 'Install Apache JMeter'
        - script: apache-jmeter-$(jmeterVersion)/bin/./jmeter -n -t LoadTest.jmx -o Results.xml -Jhostname=$(STAGING_HOSTNAME)
          displayName: 'Run Load tests'
        - script: |
            sudo apt-get update
            sudo apt-get install xsltproc
            xsltproc JMeter2JUnit.xsl Results.xml > JUnit.xml
          displayName: 'Transform JMeter output to JUnit'
        - task: PublishTestResults@2
          inputs:
            testResultsFormat: JUnit
            testResultsFiles: JUnit.xml
    

    Este es un resumen de los cambios:

    • El trabajo RunLoadTests realiza pruebas de carga desde un agente Linux.
    • El trabajo RunLoadTests depende del trabajo Deploy para garantizar que los trabajos se ejecuten en el orden correcto. Debe implementar el sitio web en App Service para poder ejecutar las pruebas de carga. Si no especifica esta dependencia, los trabajos de esta fase pueden ejecutarse en cualquier orden o en paralelo.
    • La primera script tarea descarga e instala JMeter. La jmeterVersion variable de canalización especifica la versión de JMeter que se va a instalar.
    • La segunda script tarea utiliza JMeter. El argumento -J configura la propiedad hostname en JMeter al leer la variable STAGING_HOSTNAME desde el flujo de trabajo.
    • La tercera script tarea instala xsltproc, un procesador XSLT y transforma la salida de JMeter en JUnit.
    • La tarea PublishTestResults@2 publica el informe JUnit resultante, JUnit.xml, en la canalización. Azure Pipelines puede ayudarle a visualizar los resultados de las pruebas.
  2. En el terminal integrado, agregue azure-pipelines.yml al índice, confirme los cambios e inserte la rama en GitHub.

    git add azure-pipelines.yml
    git commit -m "Run load tests with Apache JMeter"
    git push origin jmeter
    

Vea cómo Azure Pipelines ejecuta las pruebas

Aquí verá la ejecución de canalización. Verá que las pruebas de carga se ejecutan durante el almacenamiento provisional.

  1. En Azure Pipelines, vaya a la compilación y realice su seguimiento a medida que se ejecuta.

    Durante el almacenamiento provisional, verá que las pruebas de carga se ejecutan después de implementar el sitio web.

  2. Una vez que ha finalizado la compilación, vaya a la página de resumen.

    Captura de pantalla de Azure Pipelines, en la que se muestran las fases completadas.

    Verá que la implementación y las pruebas de carga finalizaron correctamente.

  3. Consulte el resumen en la parte superior de la página.

    Verá que el artefacto de compilación para el sitio web de Space Game está publicado como siempre. Tenga en cuenta también la sección Pruebas y cobertura , que muestra que se han superado las pruebas de carga.

    Captura de pantalla de Azure Pipelines en la que se muestra el resumen de pruebas.

  4. Seleccione el resumen de las pruebas para ver el informe completo.

    El informe muestra que se han superado ambas pruebas.

    Captura de pantalla de Azure Pipelines, en la que se muestra el informe de prueba completo.

    Si se produce un error en alguna prueba, verá los resultados detallados del error. A partir de esos resultados, podría investigar el origen del error.

    Recuerde que el archivo XSLT genera un archivo JUnit denominado JUnit.xml. El archivo JUnit responde a estas dos preguntas:

    • ¿El tiempo medio de solicitud es menor que un segundo?
    • ¿Menos del 10 % de las solicitudes tardan más de un segundo en completarse?

    El informe demuestra que se cumplen estos requisitos. Para ver más detalles, seleccione la flecha Resultado en el informe. A continuación, asegúrese de que solo esté seleccionado Aprobado.

    Recorte de pantalla del filtrado de pruebas aprobadas en el informe de pruebas

    Verá que los casos de prueba de tiempo promedio de respuesta y tiempo máximo de respuesta se realizaron correctamente.

    Captura de pantalla del informe de prueba, en la que se muestran dos casos de prueba correctos.

Nota:

Está usando el plan de App Service B1, que se ejecuta en el nivel Básico. Este plan está pensado para aplicaciones que tienen requisitos de tráfico bajos, como aplicaciones en un entorno de prueba. Debido a este plan, el rendimiento de su sitio web podría ser menor de lo esperado. En la práctica, elegiría un plan para el entorno de almacenamiento provisional que se ajuste más a su entorno de producción. Por ejemplo, los planes Estándar y Premium son para cargas de trabajo de producción. Se ejecutan en instancias de máquina virtual dedicadas.