练习 - 在 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
回想一下,“upstream”指的是 Microsoft GitHub 存储库。 项目的 Git 配置能够识别上游远程库,因为当你从 Microsoft 的存储库中创建该项目的分支并在本地克隆它时,就建立了这种关系。
稍后,你会将此分支推送到 GitHub 存储库(称作
origin
)。(可选)在 Visual Studio Code 中,打开 azure-pipelines.yml 文件。 查看初始配置。
该配置类似于在此学习路径的上一个模块中创建的配置。 它仅生成应用程序的 发布 配置。 为简洁起见,它省略了在以前的模块中设置的触发器、手动审批和测试。
注释
可以使用更可靠的配置来指定参与生成过程的分支。 例如,为了帮助验证代码质量,你可以在每次对任何分支推送更改时运行单元测试。 你还可以将应用程序部署到执行更全面测试的环境。 但仅当你有拉取请求、候选发布或将代码合并到主分支时,才能执行此部署。
有关详细信息,请参阅在构建流水线中使用 Git 和 GitHub 实现代码工作流和构建流水线触发器。
(可选)在 Visual Studio Code 中,可以查看 JMeter 测试计划文件 、LoadTest.jmx 和 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
变量。 此变量指向在 暂存 环境中的应用服务上运行的站点主机名。 还可以设置 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 - 非功能测试 项目。
在“Pipelines”下,选择“Library”。
选择“发布”变量组。
在“变量”下,选择“+添加”。
对于变量的名称,请输入 STAGING_HOSTNAME。 对于其值,请输入与 暂存 环境相对应的应用服务实例的 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
作业,以确保作业按正确的顺序运行。 需要先将网站部署到应用服务,然后才能运行负载测试。 如果未指定此依赖性,则阶段中的作业可以按任何顺序运行,也可以并行运行。 - 第一个
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 文件回答了以下两个问题:
- 平均请求时间是否小于 1 秒?
- 是否少于 10% 的请求需要超过 1 秒才能完成?
报告证明满足这些要求。 若要查看更多详细信息,请选择报表中的 “结果 ”箭头。 然后确保仅选中“通过”。
你会看到 平均响应时间 和 最大响应时间 测试用例都成功。
注释
你使用的是在基本层上运行的 B1 应用服务计划。 此计划适用于流量要求较低的应用,例如测试环境中的应用。 由于此计划,网站的性能可能低于预期。 实际操作时,可以选择一个与生产环境更匹配的适用于“过渡”环境的计划。 例如,标准和高级计划适用于生产工作负荷。 这些实例在专用虚拟机实例上运行。