Övning – Köra belastningstester i Azure Pipelines

Slutförd

I det här avsnittet kör du testplanen som du skapade i versionspipelinen. Testplanen använder Apache JMeter för att köra belastningstester.

Så här kör du testerna:

  • Hämta och kolla in en Git-gren som implementerar testerna.
  • Ändra pipelinen för att installera JMeter, kör testplanen, transformera resultatet till JUnit och publicera resultatet till Azure Pipelines.
  • Skicka grenen till GitHub, titta på testerna som körs i Azure Pipelines och granska sedan resultaten.

Hämta grenen från GitHub

I det här avsnittet hämtar du jmeter-grenen från GitHub och checkar ut eller växlar till den grenen.

Den här grenen innehåller projektet Space Game som du arbetade med i tidigare moduler. Den innehåller också en Azure Pipelines-konfiguration att börja med.

  1. Öppna den integrerade terminalen i Visual Studio Code.

  2. Om du vill ladda ned en gren med namnet jmeter från Microsoft-lagringsplatsen och växla till den grenen kör du följande git fetch- och git checkout-kommandon:

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

    Kom ihåg att upstream syftar på Microsoft GitHub-lagringsplatsen. Ditt projekts Git-konfiguration förstår den överordnade fjärrplatsen eftersom du konfigurerade den relationen när du förgrenade projektet från Microsoft-lagringsplatsen och klonade det lokalt.

    Snart skickar du den här grenen till din GitHub-lagringsplats, som kallas origin.

  3. Valfritt kan du öppna filen azure-pipelines.yml i Visual Studio Code. Granska den inledande konfigurationen.

    Konfigurationen liknar de som du skapade i tidigare moduler i den här utbildningsvägen. Den bygger bara programmets Version konfiguration. I korthet utelämnar den utlösare, manuella godkännanden och tester som du har konfigurerat i tidigare moduler.

    Notis

    En mer robust konfiguration kan ange de grenar som deltar i byggprocessen. För att verifiera kodkvaliteten kan du till exempel köra enhetstester varje gång du pushar en ändring på en gren. Du kan också distribuera programmet till en miljö som utför mer omfattande testning. Men du gör bara den här distributionen när du har en pull request, när du har en release candidate, eller när du sammanfogar kod till main.

    Mer information finns i Implementera ett kodarbetsflöde i din byggpipeline genom att använda Git och GitHub och Byggpipelineutlösare.

  4. I Visual Studio Code kan du också kolla in JMeter-testplansfilen LoadTest.jmxoch XLST-transformering JMeter2JUnit.xsl. XLST-filen omvandlar JMeter-utdata till JUnit så att Azure Pipelines kan visualisera resultaten.

Lägga till variabler i Azure Pipelines

Teamets ursprungliga testplan innehåller ett hårdkodat värde för hostnamnet för webbplatsen Space Game som körs i stagingmiljö.

För att göra testplanen mer flexibel använder din version en JMeter-egenskap. Tänk på en egenskap som en variabel som du kan ange från kommandoraden.

Så här definieras variabeln hostname i JMeter:

Skärmbild av hur du anger värdnamnsvariabeln i Apache JMeter.

Så här använder variabeln hostname funktionen __P för att läsa variabeln hostname.

Skärmbild för att läsa variabeln värdnamn i Apache JMeter.

Motsvarande testplanfil, LoadTest.jmx, anger den här variabeln och använder den för att ange värdnamnet.

När du kör JMeter från kommandoraden använder du argumentet -J för att ange egenskapen hostname. Här är ett exempel:

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

Här anger du variabeln STAGING_HOSTNAME i Azure Pipelines. Den här variabeln pekar på webbplatsens värdnamn som körs på App Service i din stagingmiljö. Du anger också jmeterVersion för att ange vilken version av JMeter som ska installeras.

När agenten körs exporteras dessa variabler automatiskt till agenten som miljövariabler, så din pipelinekonfiguration kan köra JMeter på det här sättet:

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

Nu ska vi lägga till pipelinevariablerna innan du uppdaterar pipelinekonfigurationen. Så här gör du:

  1. I Azure DevOps går du till ditt Space Game – web – Icke-funktionella tester projektet.

  2. Under Pipelinesväljer du Library.

  3. Välj variabelgruppen Release.

  4. Under Variablerväljer du + Lägg till.

  5. Som namn på variabeln anger du STAGING_HOSTNAME. För värdet anger du URL:en för App Service-instansen som motsvarar din mellanlagring miljö, till exempel tailspin-space-game-web-staging-1234.azurewebsites.net.

    Viktig

    Inkludera inte http://- eller https://-protokollprefixet i ditt värde. JMeter tillhandahåller protokollet när testerna körs.

  6. Lägg till en andra variabel med namnet jmeterVersion. För värdet anger du 5.4.3.

    Not

    Det här är den version av JMeter som vi senast använde för att testa den här modulen. Information om hur du hämtar den senaste versionen finns i Ladda ned Apache JMeter.

  7. Om du vill spara variabeln i pipelinen väljer du Spara längst upp på sidan.

    Din variabelgrupp liknar den som visas i följande bild:

    Skärmbild av Azure Pipelines som visar variabelgruppen. Gruppen innehåller fem variabler.

Ändra pipelinekonfigurationen

I det här avsnittet ändrar du pipelinen så att den kör belastningstesterna under mellanlagring fas.

  1. Öppna filen azure-pipelines.yml i Visual Studio Code. Ändra sedan filen på följande sätt:

    Tips

    Du kan ersätta hela filen eller bara uppdatera den del som är markerad.

    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
    

    Här är en sammanfattning av ändringarna:

    • RunLoadTests-jobbet utför lasttestning med en Linux-agent.
    • Jobb RunLoadTests är beroende av jobb Deploy för att säkerställa att jobben körs i rätt ordning. Du måste distribuera webbplatsen till App Service innan du kan köra belastningstesterna. Om du inte anger det här beroendet kan jobb i fasen köras i valfri ordning eller köras parallellt.
    • Den första script uppgiften laddar ned och installerar JMeter. Variabeln jmeterVersion pipeline anger vilken version av JMeter som ska installeras.
    • Den andra script-uppgiften kör JMeter. Argumentet -J anger egenskapen hostname i JMeter genom att läsa variabeln STAGING_HOSTNAME från pipelinen.
    • Den tredje script-uppgiften installerar xsltproc, en XSLT-processor och omvandlar JMeter-utdata till JUnit.
    • Uppgiften PublishTestResults@2 publicerar den resulterande JUnit-rapporten JUnit.xmli pipelinen. Azure Pipelines kan hjälpa dig att visualisera testresultaten.
  2. I den integrerade terminalen lägger du till azure-pipelines.yml i indexet, checkar in ändringarna och push-överför grenen till GitHub.

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

Titta på när Azure Pipelines kör testerna

Här tittar du på hur pipelineen körs. Du kommer att se belastningstesterna köras under staging.

  1. I Azure Pipelines går du till builden och övervakar den när den körs.

    Under stagingfasen, ser du att belastningstester körs efter att webbplatsen har distribuerats.

  2. När bygget är klart går du till sammanfattningssidan.

    Skärmbild av Azure Pipelines som visar de slutförda stegen.

    Du ser att distributionen och belastningstesterna har slutförts.

  3. Anteckna sammanfattningen längst upp på sidan.

    Du ser att byggartefakten för webbplatsen Space Game publiceras precis som alltid. Observera även avsnittet Tester och täckning, som visar att belastningstesterna har godkänts.

    En skärmbild av Azure Pipelines som visar testsammanfattningen.

  4. Välj testsammanfattningen för att se den fullständiga rapporten.

    Rapporten visar att båda testerna har godkänts.

    Skärmbild av Azure Pipelines som visar den fullständiga testrapporten.

    Om något test skulle misslyckas skulle du se detaljerade resultat av felet. Utifrån dessa resultat kan du undersöka orsaken till felet.

    Kom ihåg att XSLT-filen skapar en JUnit-fil med namnet JUnit.xml. JUnit-filen besvarar följande två frågor:

    • Är den genomsnittliga begärandetiden mindre än en sekund?
    • Tar det mer än en sekund att slutföra färre än 10 procent av förfrågningarna?

    Rapporten visar att dessa krav är uppfyllda. Om du vill se mer information väljer du pilen Outcome i rapporten. Kontrollera sedan att endast Godkänd är markerad.

    Skärmbild av filtrering av godkända tester i testrapporten.

    Du ser att genomsnittlig svarstid och maximal svarstid båda testfallen lyckades.

    Skärmbild av testrapporten som visar två lyckade testfall.

Anteckning

Du använder B1 App Service-plan som körs på nivån Basic. Den här planen är avsedd för appar som har låga trafikkrav, till exempel appar i en testmiljö. På grund av den här planen kan prestandan för din webbplats vara mindre än du förväntar dig. I praktiken väljer du en plan för mellanlagring miljö som bättre matchar din produktionsmiljö. Till exempel är Standard och Premium plan för produktionslaster. Dessa körs på dedikerade virtuella datorinstanser.