練習 - 在 Azure Pipelines 中執行負載測試
在本節中,您會執行您在發行管線中建立的測試計劃。 測試計劃會使用 Apache JMeter 來執行負載測試。
以下是執行測試的方式:
- 擷取並簽出一個實作測試的 Git 分支。
- 修改您的管線以安裝 JMeter、執行測試計劃、將結果轉換成 JUnit,然後將結果發佈至 Azure Pipelines。
- 將您的分支推送至 GitHub、監看 Azure Pipelines 中執行的測試,然後檢查結果。
從 GitHub 擷取分支
在本節中,您會從 GitHub 擷取 jmeter
分支,並簽出或切換至該分支。
此分支包含您在先前課程模組中使用的 Space Game 專案。 其也包含可供開始使用的 Azure Pipelines 設定。
在 Visual Studio Code 中,開啟整合式終端。
執行下列
git fetch
與git checkout
命令,以從 Microsoft 的存放庫下載名為jmeter
的分支,並切換至該分支:git fetch upstream jmeter git checkout -B jmeter upstream/jmeter
請回想一下,upstream 指的是 Microsoft GitHub 存放庫。 您專案的 Git 設定可辨識上游遠端存放庫,因為當您從 Microsoft 的存放庫派生專案並在本機加以複製時,便已為其設定了關聯性。
不久後,您就會將此分支推送至自己的 GitHub 存放庫,名為
origin
。在 Visual Studio Code 中,可以選擇性地開啟 azure-pipelines.yml 檔案。 檢閱初始設定。
該設定類似於您在此學習路徑的先前課程模組中所建立的設定。 其只會建置應用程式的發行設定。 為了簡潔起見,它會省略您在先前課程模組中設定的觸發程序、手動核准與測試。
注意
更健全的設定可能會指定參與組建流程的分支。 例如,為協助驗證程式碼品質,您可以在每次在任何分支上推送變更時執行單元測試。 您也可以將應用程式部署到執行更詳盡測試的環境。 但是,只有當您有提取要求、有候選版,或將程式碼合併到 main 時,才會進行此部署。
如需詳細資訊,請參閱使用 Git 和 GitHub 在組建管線實作程式碼流程和組建管線觸發程序。
在 Visual Studio Code 中,您可以選擇性地簽出 JMeter 測試計劃檔案 (LoadTest) 和 XLST 轉換 (JMeter2JUnit.xsl)。 XLST 檔案會將 JMeter 輸出轉換為 JUnit,讓 Azure Pipelines 可以將結果視覺化。
將變數新增至 Azure Pipelines
小組的原始測試計劃為在預備環境中所執行 Space Game 網站的主機名稱,提供硬式編碼的值。
為了讓測試計劃更有彈性,您的版本會使用 JMeter 屬性。 將屬性想成可從命令列設定的變數。
以下是在 JMeter 中定義 hostname
變數的方式:
以下是 hostname
變數使用 __P 函式讀取 hostname
變數的方式。
對應的測試計劃檔案 LoadTest.jmx 會指定此變數,並加以使用來設定主機名稱。
從命令列執行 JMeter 時,您會使用 -J
引數來設定 hostname
屬性。 以下是範例:
apache-jmeter-5.4.3/bin/./jmeter -n -t LoadTest.jmx -o Results.xml -Jhostname=tailspin-space-game-web-staging-1234.azurewebsites.net
您可以在這裡設定 Azure Pipelines 中的 STAGING_HOSTNAME
變數。 此變數會指向您網站的主機名稱,該主機會在預備環境的 App Service 上執行。 您也會設定 jmeterVersion
,以指定要安裝的 JMeter 版本。
當代理程式執行時,這些變數會自動匯出至代理程式做為環境變數,因此,您的管線設定可以透過這種方式執行 JMeter:
apache-jmeter-5.4.3/bin/./jmeter -n -t LoadTest.jmx -o Results.xml -Jhostname=$(STAGING_HOSTNAME)
現在,讓我們先新增管線變數,然後再更新您的管線設定。 若要這麼做︰
在 Azure DevOps 中,移至您的 Space Game - web - Nonfunctional tests 專案。
在 [管線] 下,選取 [程式庫]。
選取 [發行] 變數群組。
在 [變數] 下,選取 [+ 新增]。
針對您的變數名稱,輸入 STAGING_HOSTNAME。 針對其值,輸入 App Service 執行個體的 URL,此 URL 對應至您的預備環境,例如 tailspin-space-game-web-staging-1234.azurewebsites.net。
重要
請不要在您的值中包含
http://
或https://
通訊協定首碼。 JMeter 會在測試執行時提供通訊協定。新增名為 jmeterVersion 的第二個變數。 針對其值,指定 5.4.3。
注意
這是我們上次用來測試此課程模組的 JMeter 版本。 若要取得最新版本,請參閱下載 Apache JMeter (英文)。
若要將您的變數儲存至管線,請選取頁面頂端附近的 [儲存]。
您的變數群組類似於下圖所示的群組:
修改管線設定
在本節中,您會修改管線,以在預備階段期間執行負載測試。
在 Visual Studio Code 中,開啟 azure-pipelines.yml 檔案。 然後修改檔案,如下所示:
提示
您可以取代整個檔案,或只更新醒目提示的部分。
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
以下為變更摘要:
RunLoadTests
作業會從 Linux 代理程式執行負載測試。RunLoadTests
作業相依於Deploy
作業,以確保這些作業是以正確順序執行。 您必須先將網站部署到 App Service,然後才能執行負載測試。 如果您未指定此相依性,階段內的作業可以依任何順序執行或平行執行。- 第一個
script
工作會下載並安裝 JMeter。jmeterVersion
管線變數會指定要安裝的 JMeter 版本。 - 第二個
script
工作會執行 JMeter。-J
引數會透過從管線讀取STAGING_HOSTNAME
變數來設定 JMeter 中的hostname
屬性。 - 第三個
script
工作會安裝 xsltproc (一個 XSLT 處理器),並將 JMeter 輸出轉換為 JUnit。 PublishTestResults@2
工作會將產生的 JUnit 報告 (JUnit.xml) 發佈至管線。 Azure Pipelines 可協助您將測試結果視覺化。
在整合式終端中,將 azure-pipelines.yml 新增至索引、認可變更,然後將分支向上推送至 GitHub。
git add azure-pipelines.yml git commit -m "Run load tests with Apache JMeter" git push origin jmeter
觀察 Azure Pipelines 執行測試
您可以在這裡監看管線執行。 您會在預備期間看到負載測試執行。
在 Azure Pipelines 中,移至組建並在該組建執行時加以追蹤。
在「預備」期間,您會在網站完成部署之後看到負載測試執行。
建置完成後,請移至摘要頁面。
您會看到部署和負載測試順利完成。
請注意頁面頂端附近的摘要。
您會看到 Space Game 網站的組建成品與往常一樣進行發佈。 亦請注意 [測試和涵蓋範圍] 區段,其中顯示負載測試已通過。
選取測試摘要來查看完整的報告。
報告顯示這兩個測試都已通過。
如果有任何測試失敗,您會看到失敗的詳細結果。 您可以從這些結果調查失敗的來源。
回想一下,XSLT 檔案會產生名為 JUnit.xml 的 JUnit 檔案。 JUnit 檔案回答下列兩個問題:
- 平均要求時間小於一秒嗎?
- 少於 10% 的要求需要一秒以上的時間才能完成嗎?
此報告證明符合這些需求。 若要查看更多詳細資料,請選取報告中的 [結果] 箭號。 然後,確定只選取 [已通過]。
您會看到 [平均回應時間] 和 [最大回應時間] 測試案例都成功。
注意
您使用的是 B1 App Service 方案,其會在基本層上執行。 此方案適用於具有低流量需求的應用程式,例如測試環境中的應用程式。 由於此方案,您的網站效能可能會比您預期的還要低。 實務上,您會針對更密切符合您生產環境的預備環境選擇一個方案。 例如,標準與進階方案適用於生產工作負載。 這些方案會在專用的虛擬機器執行個體上執行。