Esercizio - Eseguire test di carico in Azure Pipelines

Completato

In questa sezione si eseguirà il piano di test creato nella pipeline di rilascio. Il piano di test usa Apache JMeter per eseguire test di carico.

Ecco come eseguire i test:

  • Recuperare ed eseguire il checkout di un ramo Git che implementi i test.
  • Modificare la pipeline per installare JMeter, eseguire il piano di test, trasformare i risultati in JUnit e pubblicare i risultati in Azure Pipelines.
  • Esegui il push del ramo su GitHub, guarda i test eseguiti in Azure Pipelines e quindi esamina i risultati.

Recuperare il ramo da GitHub

In questa sezione verrà recuperato il ramo jmeter da GitHub e si eseguirà il checkout o il passaggio a tale ramo.

Questo ramo contiene il progetto Space Game usato nei moduli precedenti. Contiene anche una configurazione di Azure Pipelines per iniziare.

  1. Aprire il terminale integrato in Visual Studio Code.

  2. Eseguire i comandi git fetch e git checkout seguenti per scaricare un ramo denominato jmeter dal repository di Microsoft e passare a tale ramo:

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

    Tenere presente che upstream fa riferimento al repository Microsoft GitHub. La configurazione Git del progetto comprende l'upstream remoto perché la relazione è stata configurata quando il progetto è stato copiato tramite fork dal repository Microsoft e clonato in locale.

    In breve, si eseguirà il push di questo ramo al repository GitHub personale, noto come origin.

  3. Facoltativamente, in Visual Studio Code aprire il file azure-pipelines.yml . Esaminare la configurazione iniziale.

    La configurazione è simile a quella creata nei moduli precedenti in questo percorso di apprendimento. Compila solo la configurazione release dell'applicazione. Per brevità, omette i trigger, le approvazioni manuali e i test configurati nei moduli precedenti.

    Annotazioni

    Una configurazione più solida potrebbe specificare i rami che fanno parte del processo di compilazione. Ad esempio, per verificare la qualità del codice, è possibile eseguire unit test ogni volta che si esegue il push di una modifica in qualsiasi ramo. È anche possibile distribuire l'applicazione in un ambiente che esegue test più completi. Questa distribuzione viene tuttavia eseguita solo quando si dispone di una richiesta pull, quando si ha un candidato per la versione o quando si unisce il codice a main.

    Per altre informazioni, vedere Implementare un flusso di lavoro di codice nella pipeline di compilazione usando Git e GitHub e i trigger della pipeline di compilazione.

  4. Facoltativamente, in Visual Studio Code è possibile controllare il file del piano di test JMeter, LoadTest.jmx e la trasformazione XLST, JMeter2JUnit.xsl. Il file XLST trasforma l'output di JMeter in JUnit in modo che Azure Pipelines possa visualizzare i risultati.

Aggiungere variabili ad Azure Pipelines

Il piano di test originale del team fornisce un valore hardcoded per il nome host del sito Web di Space Game che viene eseguito nell'ambiente di staging.

Per rendere più flessibile il piano di test, la versione usa una proprietà JMeter. Si consideri una proprietà come una variabile che è possibile impostare dalla riga di comando.

Ecco come viene definita la hostname variabile in JMeter:

Screenshot dell'impostazione della variabile hostname in Apache JMeter.

Ecco come la hostname variabile usa la funzione __P per leggere la hostname variabile.

Screenshot per la lettura della variabile hostname in Apache JMeter.

Il file del piano di test corrispondente , LoadTest.jmx, specifica questa variabile e la usa per impostare il nome host.

Quando si esegue JMeter dalla riga di comando, si usa l'argomento -J per impostare la proprietà hostname. Ecco un esempio:

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

In questa sezione viene impostata la STAGING_HOSTNAME variabile in Azure Pipelines. Questa variabile punta al nome host del sito in esecuzione nel servizio app nell'ambiente di staging. È anche necessario impostare il jmeterVersion per specificare la versione di JMeter da installare.

Quando l'agente viene eseguito, queste variabili vengono esportate automaticamente nell'agente come variabili di ambiente, in modo che la configurazione della pipeline possa eseguire JMeter in questo modo:

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

Aggiungiamo ora le variabili della pipeline, prima di aggiornare la configurazione della pipeline. A questo scopo:

  1. In Azure DevOps, passare al progetto Space Game - web - Test non funzionali.

  2. In Pipeline selezionare Libreria.

  3. Selezionare il gruppo di variabili Rilascio.

  4. In Variabili selezionare + Aggiungi.

  5. Per il nome della variabile, immettere STAGING_HOSTNAME. Come valore, immettere l'URL dell'istanza del servizio app corrispondente all'ambiente di staging, ad esempio tailspin-space-game-web-staging-1234.azurewebsites.net.

    Importante

    Non includere il prefisso del protocollo http:// o https:// nel tuo valore. JMeter fornisce il protocollo quando vengono eseguiti i test.

  6. Aggiungere una seconda variabile denominata jmeterVersion. Per il valore, specificare 5.4.3.

    Annotazioni

    Questa è la versione di JMeter usata per l'ultima volta per testare questo modulo. Per ottenere la versione più recente, vedere Scaricare Apache JMeter.

  7. Per salvare la variabile nella pipeline, selezionare Salva nella parte superiore della pagina.

    Il gruppo di variabili è simile a quello illustrato nell'immagine seguente:

    Screenshot di Azure Pipelines che mostra il gruppo di variabili. Il gruppo contiene cinque variabili.

Modificare la configurazione della pipeline

In questa sezione modificherai la pipeline per eseguire i test di carico durante la fase di Staging.

  1. In Visual Studio Code aprire il file azure-pipelines.yml. Modificare quindi il file come segue:

    Suggerimento

    È possibile sostituire l'intero file o semplicemente aggiornare la parte evidenziata.

    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
    

    Ecco un riepilogo delle modifiche:

    • Il processo RunLoadTests esegue il test di carico da un agente Linux.
    • Il processo RunLoadTests dipende dal processo Deploy per garantire che i processi vengano eseguiti nell'ordine corretto. È necessario distribuire il sito Web nel servizio app prima di poter eseguire i test di carico. Se non si specifica questa dipendenza, i processi all'interno della fase possono essere eseguiti in qualsiasi ordine o in parallelo.
    • La prima script attività scarica e installa JMeter. La jmeterVersion variabile della pipeline specifica la versione di JMeter da installare.
    • La seconda attività script esegue JMeter. L'argomento -J imposta la hostname proprietà in JMeter leggendo la STAGING_HOSTNAME variabile dalla pipeline.
    • La terza script attività installa xsltproc, un processore XSLT e trasforma l'output JMeter in JUnit.
    • L'attività PublishTestResults@2 pubblica il report JUnit risultante, JUnit.xml, nella pipeline. Azure Pipelines consente di visualizzare i risultati dei test.
  2. Nel terminale integrato aggiungere azure-pipelines.yml all'indice, eseguire il commit delle modifiche ed eseguire il push del ramo in GitHub.

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

Osservare l'esecuzione dei test in Azure Pipelines

Qui si può osservare l'esecuzione della pipeline. Verranno visualizzati i test di carico eseguiti durante la gestione temporanea.

  1. In Azure Pipelines passare alla compilazione e tracciarne l'esecuzione.

    Durante la gestione temporanea, i test di carico vengono eseguiti dopo la distribuzione del sito Web.

  2. Al completamento della compilazione, passare alla pagina di riepilogo.

    Screenshot di Azure Pipelines, che mostra le fasi completate.

    Si noterà che la distribuzione e i test di carico sono stati completati correttamente.

  3. Osservare il riepilogo nella parte superiore della pagina.

    Si noterà che l'artefatto della compilazione per il sito Web Space Game viene pubblicato normalmente. Si noti anche la sezione Test e copertura , che mostra che i test di carico sono stati superati.

    Screenshot di Azure Pipelines che illustra il riepilogo del test.

  4. Selezionare il riepilogo dei test per visualizzare il report completo.

    Il report mostra che entrambi i test sono stati superati.

    Screenshot di Azure Pipelines, che mostra il report di test completo.

    Se un test dovesse avere esito negativo, vengono visualizzati i risultati dettagliati dell'errore. Da questi risultati, è possibile analizzare l'origine dell'errore.

    Tenere presente che il file XSLT produce un file JUnit denominato JUnit.xml. Il file JUnit risponde alle due domande seguenti:

    • Il tempo medio della richiesta è inferiore a un secondo?
    • Meno del 10 percento delle richieste impiega più di un secondo per essere completato?

    La relazione dimostra che questi requisiti sono soddisfatti. Per visualizzare altri dettagli, selezionare la freccia Risultato nel report. Assicurarsi quindi che sia selezionata solo l'opzione Passato .

    Screenshot dei test superati di Fitlering nel report del test.

    Si noterà che entrambi i test case Average Response Time e Max Response Time hanno avuto esito positivo.

    Screenshot del rapporto di prova che mostra due casi di prova riusciti.

Annotazioni

Stai utilizzando il piano di servizio app B1, che viene eseguito nel livello Base. Questo piano è destinato alle app con requisiti di traffico limitati, ad esempio le app in un ambiente di test. A causa di questo piano, le prestazioni del sito Web potrebbero essere inferiori a quelle previste. In pratica, è necessario scegliere un piano per l'ambiente di staging che corrisponda maggiormente all'ambiente di produzione. Ad esempio, i piani Standard e Premium sono destinati ai carichi di lavoro di produzione. Vengono eseguiti in istanze di macchina virtuale dedicate.