Exercice - Effectuer des tests de charge dans Azure Pipelines
Dans cette section, vous allez exécuter le plan de test que vous avez créé dans le pipeline de mise en production. Le plan de test utilise Apache JMeter pour effectuer des tests de charge.
Voici comment vous effectuez les tests :
- Récupérez et extrayez une branche Git qui implémente les tests.
- Modifiez votre pipeline pour installer JMeter, exécutez le plan de test, transformez les résultats en JUnit et publiez les résultats sur Azure Pipelines.
- Poussez votre branche vers GitHub, observez les tests exécutés dans Azure Pipelines, puis examinez les résultats.
Récupérer (fetch) la branche à partir de GitHub
Dans cette section, vous allez récupérer la branche jmeter
à partir de GitHub pour l’extraire ou pour passer à celle-ci.
Cette branche contient le projet Space Game que vous avez utilisé dans les modules précédents. Elle contient également une configuration Azure Pipelines qui vous permet de démarrer.
Dans Visual Studio Code, ouvrez le terminal intégré.
Pour télécharger une branche nommée
jmeter
à partir du dépôt Microsoft, passez à cette branche, puis exécutez les commandesgit fetch
etgit checkout
suivantes :git fetch upstream jmeter git checkout -B jmeter upstream/jmeter
Rappelez-vous que upstream (amont) fait référence au dépôt GitHub Microsoft. La configuration Git de votre projet comprend le dépôt distant upstream (amont), car vous avez configuré cette relation quand vous avez dupliqué le projet à partir du dépôt de Microsoft et que vous l’avez cloné localement.
Dans quelques instants, vous pousserez (push) cette branche vers votre dépôt GitHub appelé
origin
.Si vous le souhaitez, dans Visual Studio Code, ouvrez le fichier azure-pipelines.yml. Examinez la configuration initiale.
La configuration ressemble à celles que vous avez créées dans les modules précédents de ce parcours d’apprentissage. Elle crée seulement la configuration Production de l’application. Par souci de concision, la configuration omet les déclencheurs, les approbations manuelles et les tests que vous avez configurés dans les modules précédents.
Notes
Pour une configuration plus robuste, les branches qui participent au processus de génération pourraient être spécifiées. Par exemple, pour faciliter la vérification de la qualité du code, vous pouvez effectuer des tests unitaires chaque fois que vous poussez une modification dans une branche. Vous pouvez aussi déployer l’application sur un environnement qui effectue des tests plus exhaustifs. Toutefois, vous ne procédez à ce déploiement que lorsque vous avez une requête de tirage (pull request), lorsque vous disposez d'une version Release Candidate, ou lorsque vous fusionnez du code sur la base de type primaire.
Pour plus d’informations, consultez Implémenter un workflow de code dans votre pipeline de build à l’aide de Git et GitHub et Déclencheurs de pipeline de build.
Si vous le souhaitez, dans Visual Studio Code, vous pouvez extraire le fichier de plan de test JMeter, LoadTest.jmx, et la transformation XSLT, JMeter2JUnit.xsl. Le fichier XSLT transforme la sortie JMeter en JUnit afin qu’Azure Pipelines puisse visualiser les résultats.
Ajouter des variables à Azure Pipelines
Le plan de test d’origine de l’équipe fournit une valeur codée en dur pour le nom d’hôte du site web Space Game qui s’exécute dans l’environnement intermédiaire.
Pour rendre le plan de test plus flexible, votre version utilise une propriété JMeter. Vous pouvez considérer une propriété comme une variable que vous pouvez définir à partir de la ligne de commande.
Voici comment la variable hostname
est définie dans JMeter :
Voici comment la variable hostname
utilise la fonction __P pour lire la variable hostname
.
Le fichier de plan de test correspondant, LoadTest.jmx, spécifie cette variable et l’utilise pour définir le nom d’hôte.
Quand vous exécutez JMeter à partir de la ligne de commande, vous utilisez l’argument -J
pour définir la propriété hostname
. Voici un exemple :
apache-jmeter-5.4.3/bin/./jmeter -n -t LoadTest.jmx -o Results.xml -Jhostname=tailspin-space-game-web-staging-1234.azurewebsites.net
Ici, vous définissez la variable STAGING_HOSTNAME
dans Azure Pipelines. Cette variable pointe vers le nom d’hôte de votre site qui s’exécute sur App Service dans votre environnement de préproduction. Vous définissez aussi jmeterVersion
pour spécifier la version de JMeter à installer.
Quand l’agent s’exécute, ces variables sont exportées automatiquement vers l’agent en tant que variables d’environnement afin que la configuration de votre pipeline puisse exécuter JMeter de cette façon :
apache-jmeter-5.4.3/bin/./jmeter -n -t LoadTest.jmx -o Results.xml -Jhostname=$(STAGING_HOSTNAME)
Nous allons maintenant ajouter les variables de pipeline avant de mettre à jour la configuration de votre pipeline. Pour ce faire :
Dans Azure DevOps, accédez à votre projet Space Game - web - Nonfunctional tests.
Sous Pipelines, sélectionnez Bibliothèques.
Sélectionnez le groupe de variables Release.
Sous Variables, sélectionnez + Ajouter.
Pour le nom de votre variable, entrez STAGING_HOSTNAME. Comme valeur, entrez l’URL de l’instance App Service qui correspond à votre environnement de préproduction, par exemple tailspin-space-game-web-staging-1234.azurewebsites.net.
Important
N’incluez pas le préfixe de protocole
http://
ouhttps://
dans votre valeur. JMeter fournit le protocole lors de l’exécution des tests.Ajoutez une deuxième variable nommée jmeterVersion. Pour sa valeur, spécifiez 5.4.3.
Notes
Il s’agit de la version de JMeter que nous avons utilisée pour tester ce module. Pour obtenir la version la plus récente, consultez Télécharger Apache JMeter.
Sélectionnez Enregistrer en haut de la page pour enregistrer votre variable dans le pipeline.
Votre groupe de variables ressemble à celui montré dans l’image suivante :
Modifier la configuration du pipeline
Dans cette section, vous modifierez le pipeline pour exécuter vos tests de charge pendant l’étape Mise en lots.
Dans Visual Studio Code, ouvrez le fichier azure-pipelines.yml. Ensuite, modifiez le fichier comme suit :
Conseil
Vous pouvez remplacer le fichier entier ou simplement mettre à jour la partie mise en surbrillance.
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
Voici un résumé de ces modifications :
- Le travail
RunLoadTests
effectue des tests de charge à partir d’un agent Linux. - Le travail
RunLoadTests
dépend du travailDeploy
pour garantir que les travaux s’exécutent dans le bon ordre. Vous devez déployer le site web sur App Service avant de pouvoir exécuter les tests de charge. Si vous ne spécifiez pas cette dépendance, les travaux de cette phase peuvent s’exécuter dans n’importe quel ordre ou en parallèle. - La première tâche du
script
télécharge et installe JMeter. La variable de pipelinejmeterVersion
spécifie la version de JMeter à installer. - La deuxième tâche du
script
exécute JMeter. L’argument-J
définit la propriétéhostname
dans JMeter en lisant la variableSTAGING_HOSTNAME
à partir du pipeline. - La troisième tâche du
script
installe xsltproc, un processeur XSLT, et transforme la sortie JMeter en JUnit. - La tâche
PublishTestResults@2
publie le rapport JUnit résultant, JUnit.xml, sur le pipeline. Azure Pipelines peut vous aider à visualiser les résultats des tests.
- Le travail
Dans le terminal intégré, ajoutez azure-pipelines.yml à l’index, commitez les modifications, puis poussez la branche sur GitHub.
git add azure-pipelines.yml git commit -m "Run load tests with Apache JMeter" git push origin jmeter
Regarder Azure Pipelines exécuter les tests
Ici, vous observerez l’exécution du pipeline. Vous verrez l’exécution des tests de charge dans la phase Mise en lots.
Dans Azure Pipelines, accédez à la build et effectuez son suivi lors de son exécution.
Pendant la phase Préproduction, vous voyez que les tests de charge s’exécutent après le déploiement du site web.
Une fois la build terminée, accédez à la page récapitulative.
Vous voyez que le déploiement et les tests de charge se sont terminés avec succès.
Dans la partie supérieure de la page, notez le récapitulatif.
Vous voyez que l’artefact de build pour le site web Space Game est publié comme toujours. Notez également la section Tests and coverage qui indique que les tests de charge ont réussi.
Sélectionnez le récapitulatif des tests pour voir le rapport complet.
Le rapport indique que les deux tests ont réussi.
Si un test a échoué, vous verrez les résultats détaillés de l’échec. À partir de ces résultats, vous pouvez rechercher la source de l’échec.
Rappelez-vous que le fichier XSLT produit un fichier JUnit, nommé JUnit.xml. Le fichier JUnit répond à ces deux questions :
- La durée moyenne d’une requête est-elle inférieure à une seconde ?
- Moins de 10 % des requêtes ont-elles une durée supérieure à une seconde ?
Le rapport prouve que ces exigences sont satisfaites. Pour voir plus de détails, sélectionnez la flèche Outcome dans le rapport. Vérifiez ensuite que seule l’option Passed est sélectionnée.
Vous constatez que les deux cas de test Temps de réponse moyen et Temps de réponse maximal ont réussi.
Remarque
Vous utilisez le plan App Service B1, qui s’exécute sur le niveau De base. Ce plan est conçu pour les applications qui ont des exigences de trafic faibles, comme des applications dans un environnement de test. En raison de ce plan, les performances de votre site web peuvent être inférieures à celles que vous attendez. Dans la pratique, vous devez choisir un plan pour l’environnement intermédiaire qui correspond le plus à votre environnement de production. Par exemple, les plans Standard et Premium sont destinés aux charges de travail de production. Ils s’exécutent sur des instances de machine virtuelle dédiées.