演習 - Azure Pipelines でロード テストを実行する
このセクションでは、リリース パイプラインで作成したテスト 計画を実行します。 テスト 計画では、Apache JMeter を使用してロード テストを実行します。
テストを実行する方法を次に示します。
- テストを実装する Git ブランチをフェッチしてチェックアウトします。
- パイプラインを変更して JMeter をインストールし、テスト計画を実行し、結果を JUnit に変換し、結果を Azure Pipelines に発行します。
- ブランチを GitHub にプッシュし、Azure Pipelines でテストが実行されているのを見て、結果を確認します。
GitHub からブランチをフェッチする
このセクションでは、GitHub から jmeter
ブランチをフェッチし、そのブランチをチェックアウトします (つまりそのブランチに切り替えます)。
このブランチには、前のモジュールで使用した Space Game プロジェクトが含まれています。 また、最初に使用する Azure Pipelines 構成も含まれています。
Visual Studio Code で、統合ターミナルを開きます。
Microsoft のリポジトリから
jmeter
という名前のブランチをダウンロードし、そのブランチに切り替えるために、次のgit fetch
およびgit checkout
コマンドを実行します。git fetch upstream jmeter git checkout -B jmeter upstream/jmeter
アップストリームが Microsoft GitHub リポジトリを参照していることを思い出してください。 Microsoft リポジトリからプロジェクトをフォークしてローカルに複製したときに、そのリレーションシップを設定したため、プロジェクトの Git 構成ではアップストリーム リモートが認識されます。
すぐに、
origin
と呼ばれる独自の GitHub リポジトリにこのブランチをプッシュします。必要に応じて、Visual Studio Code で azure-pipelines.yml ファイルを開きます。 初期構成を確認します。
構成は、このラーニング パスの前のモジュールで作成した構成に似ています。 アプリケーションの リリース 構成のみがビルドされます。 簡潔にするために、前のモジュールで設定したトリガー、手動承認、テストは省略されています。
注
より堅牢な構成では、ビルド プロセスに参加するブランチを指定できます。 たとえば、コードの品質を検証するために、いずれかのブランチに変更をプッシュするたびに、単体テストを実行できます。 さらに包括的なテストを実行する環境にアプリケーションをデプロイすることもできます。 ただし、このデプロイは、プル要求がある場合、リリース候補がある場合、またはコードを メインにマージする場合にのみ行います。
詳細については、「Git と GitHub とビルド パイプライン トリガーを使用してビルド パイプラインにコード ワークフローを実装する」を参照してください。
必要に応じて、Visual Studio Code で、JMeter テスト 計画ファイル 、LoadTest.jmx、および XLST 変換 JMeter2JUnit.xsl をチェックアウトできます。 XLST ファイルは、Azure Pipelines が結果を視覚化できるように JMeter 出力を JUnit に変換します。
Azure Pipelines に変数を追加する
チームの元のテスト計画では、ステージング環境で実行される Space Game Web サイトのホスト名にハードコーディングされた値が提供されます。
テスト計画の柔軟性を高めるために、バージョンでは 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 で実行されるサイトのホスト名を指します。 また、インストールする JMeter のバージョンを指定するように jmeterVersion
を設定します。
エージェントを実行すると、これらの変数が環境変数としてエージェントに自動的にエクスポートされるため、パイプライン構成で次のように JMeter を実行できます。
apache-jmeter-5.4.3/bin/./jmeter -n -t LoadTest.jmx -o Results.xml -Jhostname=$(STAGING_HOSTNAME)
パイプライン構成を更新する前に、パイプライン変数を追加してみましょう。 これを行うには、次の手順を実行します。
Azure DevOps で、 Space Game - Web - 非機能テスト プロジェクトに移動します。
パイプラインでライブラリを選択します。
[ リリース 変数] グループを選択します。
[ 変数] で 、[ + 追加] を選択します。
変数の名前として、「 STAGING_HOSTNAME」と入力します。 その値には、 ステージング 環境に対応する App Service インスタンスの URL ( tailspin-space-game-web-staging-1234.azurewebsites.net など) を入力します。
重要
値に
http://
またはhttps://
プロトコル プレフィックスを含めないでください。 JMeter は、テストの実行時にプロトコルを提供します。jmeterVersion という名前の 2 つ目の変数を追加します。 その値には、 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
ジョブに依存します。 ロード テストを実行する前に、Web サイトを App Service にデプロイする必要があります。 この依存関係を指定しない場合は、ステージ内のジョブを任意の順序で実行することも、並列で実行することもできます。- 最初の
script
タスクは JMeter をダウンロードしてインストールします。jmeterVersion
パイプライン変数は、インストールする JMeter のバージョンを指定します。 - 2 番目の
script
タスクは JMeter を実行します。-J
引数は、パイプラインからSTAGING_HOSTNAME
変数を読み取ることによって、JMeter のhostname
プロパティを設定します。 - 3 番目の
script
タスクは、 XSLT プロセッサである xsltproc をインストールし、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 で、ビルドに移動し、実行中にそれをトレースします。
ステージング中は、Web サイトのデプロイ後にロード テストが実行されます。
ビルドが完了したら、概要ページに移動します。
デプロイとロード テストが正常に完了したことがわかります。
ページの上部近くにある概要を確認します。
Space Game Web サイトのビルド 成果物が常に公開されていることがわかります。 また、ロード テストが成功したことを示す [ テストとカバレッジ ] セクションにも注意してください。
テストの概要を選択して、完全なレポートを表示します。
レポートには、両方のテストに合格したと表示されます。
テストが失敗した場合は、エラーの詳細な結果が表示されます。 これらの結果から、エラーの原因を調査できます。
XSLT ファイルは 、JUnit.xmlという JUnit ファイルを生成することを思い出してください。 JUnit ファイルは、次の 2 つの質問に回答します。
- 平均要求時間は 1 秒未満ですか?
- 要求の 10% 未満が完了するまでに 1 秒以上かかるか。
レポートは、これらの要件が満たされていることを証明します。 詳細を表示するには、レポートの [結果 ] 矢印を選択します。 次に、[ Passed ] のみが選択されていることを確認します。
平均応答時間と最大応答時間の両方のテスト ケースが成功したことがわかります。
注
Basic レベルで実行される B1 App Service プランを使用しています。 このプランは、テスト環境のアプリなど、トラフィック要件が低いアプリを対象としています。 このプランにより、Web サイトのパフォーマンスが予想よりも低い可能性があります。 実際には、運用環境とより密接に一致する ステージング 環境のプランを選択します。 たとえば、 Standard プランと Premium プランは運用環境のワークロード用です。 これらは専用の仮想マシン インスタンスで実行されます。