Esercizio - Eseguire test di carico in Azure Pipelines
In questa sezione viene eseguito il piano di test creato nella pipeline di versione. Il piano di test usa Apache JMeter per eseguire test di carico.
Ecco come vengono eseguiti 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.
- Eseguire il push del ramo in GitHub, osservare l'esecuzione dei test in Azure Pipelines e quindi esaminare 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.
Aprire il terminale integrato in Visual Studio Code.
Eseguire i comandi
git fetch
egit checkout
seguenti per scaricare un ramo denominatojmeter
dal repository di Microsoft e passare a tale ramo:git fetch upstream jmeter git checkout -B jmeter upstream/jmeter
Tenere presente che upstream si riferisce al repository GitHub Microsoft. La configurazione Git del progetto riconosce il repository remoto upstream perché questa relazione viene configurata quando si esegue la copia tramite fork del progetto dal repository Microsoft e lo si clona in locale.
In breve, si eseguirà il push di questo ramo al repository GitHub personale, noto come
origin
.Facoltativamente, in Visual Studio Code aprire il file azure-pipelines.yml. Rivedere la configurazione iniziale.
La configurazione è simile a quelle create nei moduli precedenti in questo percorso di apprendimento. Esegue la compilazione solo della configurazione Release dell'applicazione. Per brevità, omette i trigger, le approvazioni manuali e i test configurati nei moduli precedenti.
Nota
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 usata solo quando si ha una richiesta pull, quando si ha una versione finale candidata o quando si esegue il merge del codice in main.
Per altre informazioni, vedere Implementare un flusso di lavoro di codice nella pipeline di compilazione usando Git e GitHub e Trigger della pipeline di compilazione.
Facoltativamente, in Visual Studio Code è possibile estrarre il file del piano di test JMeter, LoadTest.jmx e la trasformazione XLST, JMeter2JUnit.xsl. Il file XLST trasforma l'output 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, verrà usata una proprietà JMeter. Si pensi a una proprietà come a una variabile che è possibile impostare dalla riga di comando.
Ecco come viene definita la variabile hostname
in JMeter:
Ecco il modo in cui la variabile hostname
usa la funzione __P per leggere la variabile hostname
.
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
Qui è possibile impostare la variabile STAGING_HOSTNAME
in Azure Pipelines. Questa variabile punta al nome host del sito in esecuzione nel servizio app nell'ambiente di staging. Si imposta anche 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)
A questo punto, aggiungere le variabili della pipeline prima di aggiornare la configurazione della pipeline. A questo scopo:
In Azure DevOps passare al progetto Space Game - Web - Test non funzionali.
In Pipeline, selezionare Libreria.
Selezionare il gruppo di variabili Rilascio.
In Variabili, selezionare + Aggiungi.
Immettere STAGING_HOSTNAME come nome della variabile. 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://
ohttps://
nel valore. JMeter fornisce il protocollo durante l'esecuzione dei test.Aggiungere una seconda variabile denominata jmeterVersion. Come valore, specificare 5.4.3.
Nota
Questa è la versione di JMeter usata l'ultima volta per testare il modulo. Per ottenere la versione più recente, vedere Download Apache JMeter.
Per salvare la variabile nella pipeline, selezionare Salva nella parte superiore della pagina.
Il gruppo di variabili è simile a quello illustrato nell'immagine seguente:
Modificare la configurazione della pipeline
In questa sezione si modificherà la pipeline per eseguire i test di carico durante la fase di staging.
In Visual Studio Code aprire il file azure-pipelines.yml. Modificare quindi il file come segue:
Suggerimento
Puoi sostituire l'intero file o aggiornare solo il percorso evidenziato.
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 processoDeploy
per assicurare 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 attività
script
scarica e installa JMeter. La variabile della pipelinejmeterVersion
specifica la versione di JMeter da installare. - La seconda attività
script
esegue JMeter. L'argomento-J
imposta la proprietàhostname
in JMeter leggendo la variabileSTAGING_HOSTNAME
dalla pipeline. - La terza attività
script
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 può essere utile per visualizzare i risultati del test.
- Il processo
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. Si noterà che i test di carico vengono eseguiti durante la fase di staging.
In Azure Pipelines passare alla compilazione e tracciarne l'esecuzione.
Durante la fase di staging si noterà che i test di carico vengono eseguiti dopo la distribuzione del sito Web.
Al completamento della compilazione, passare alla pagina di riepilogo.
Si noterà che la distribuzione e i test di carico sono stati completati correttamente.
Osservare il riepilogo nella parte superiore della pagina.
Si noterà che l'artefatto della compilazione per il sito Web Space Game viene pubblicato normalmente. Nella sezione Test e code coverage viene anche indicato che i test di carico sono stati superati.
Selezionare il riepilogo dei test per visualizzare il report completo.
Il report mostra che entrambi i test sono stati superati.
In caso di esito negativo di un test, verrebbero visualizzati i risultati dettagliati dell'errore. Da questi risultati è possibile analizzare l'origine dell'errore.
Ricordare che il file XSLT produce un file JUnit denominato JUnit.xml. Il file JUnit risponde a queste due domande:
- Il tempo medio di richiesta è inferiore a un secondo?
- Il numero di richieste che hanno impiegato più di un secondo è inferiore al 10%?
Il report dimostra che questi requisiti sono stati soddisfatti. Per visualizzare maggiori dettagli, selezionare la freccia Risultato nel report. Assicurarsi quindi che sia selezionata solo l'opzione Superato.
Si noterà che i test case del tempo medio di risposta e del tempo di risposta massimo hanno entrambi esito positivo.
Nota
Si sta usando il piano di servizio app B1, che viene eseguito nel livello Basic. Questo piano è destinato alle app con requisiti di traffico ridotto, ad esempio in un ambiente di test. A causa di questo piano, le prestazioni del sito Web potrebbero essere inferiori al previsto. 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. Questi piani vengono eseguiti in istanze di macchine virtuali dedicate.