【发布时间】:2020-02-14 08:38:30
【问题描述】:
我正在将我们的一个项目转换为使用 Azure DevOps 而不是 AppVeyor for CI。作为构建的一部分,我们使用自定义测试运行器来执行某些测试。
在 AppVeyor 中运行时,我们直接从测试运行器调用 REST API,以通知构建服务器正在运行的测试并更新它们的状态。这非常简单,如他们的 Add Tests 和 Update Tests 文档的 REST 部分所示,并且使我们能够很好地集成到 AppVeyor 的 UI。
我一直在研究如何在 Azure DevOps 中做同样的事情。我找到了adding 和updating 测试结果的REST API 部分。如果这是我在运行管道期间使用的,还是用于其他场景,从 API 文档中并不完全清楚。我一直在寻找其他尝试做同样事情的人,但到目前为止没有任何运气。大多数示例都是关于上传测试结果文件,但这似乎是一种相当间接的发布测试结果的方式,尤其是因为我想在所有测试运行之前注册它们,然后在它们完成后更新它们的状态。
关于在构建期间使用 Azure DevOps API 发布测试结果,是否有人有任何指示或示例?
详细解决方案:
有了 Merlin Liang 的指导答案,我现在已经完成了这项工作。
第 1 步。首先我创建了一个新的测试运行,我在构建作业结束时使用了一个 powershell 脚本(称为Build):
- powershell: |
$url = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/test/runs?api-version=5.0"
$body = @{
"name" = "IntegrationTests"
"build" = @{
"id" = $env:BUILD_BUILDID
}
"isAutomated" = $TRUE
"state" = "InProgress"
}
$json = $body | ConvertTo-Json
$result = Invoke-RestMethod -Method 'Post' -Uri $url -Body $json -ContentType 'application/json' -Headers @{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}
$runId = $result.id
echo "##vso[task.setvariable variable=INTEGRATION_TEST_RUN_ID;isOutput=true]$runId"
displayName: 'Create test run'
name: CreateTestRun
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
请注意,您必须在 env 部分中明确授予脚本对 System.AccessToken 的访问权限,因为默认情况下该变量不会放入环境变量中。测试运行状态应为InProgress,以确保测试在运行时显示在构建的测试列表中。
第 2 步。 接下来,我的管道将展开到并行作业中以运行测试,这需要访问我在上面创建的 INTEGRATION_TEST_RUN_ID 变量,因此我将其导入到作业中:
- job: IntegrationTests
dependsOn: Build
variables:
INTEGRATION_TEST_RUN_ID: $[ dependencies.Build.outputs['CreateTestRun.INTEGRATION_TEST_RUN_ID'] ]
strategy:
parallel: 2
...
然后我的测试运行程序(用 C# 编写)可以为 POSTing 和 PATCHing 测试构建 URL:
$"{this.apiUrl}{this.projectName}/_apis/test/runs/{this.testRunId}/results?api-version=5.0"
并添加测试附件:
$"{this.apiUrl}{this.projectName}/_apis/test/runs/{this.testRunId}/results/{testResultId}/attachments?api-version=5.0-preview.1"
那些类成员变量只是从通常的环境变量中读取的,testResultId 是我最初POST 测试时 API 返回的 ID。
当我从 Azure Pipeline YAML 调用测试运行程序并在授权标头中使用它时,我在 env 部分中明确设置了 SYSTEM_ACCESSTOKEN。
第 3 步。 最后,我再次将测试运行标记为在一个依赖于集成测试作业的专用作业中完成,即使测试失败也必须始终运行:
- job: EndIntegrationTests
dependsOn:
- Build
- IntegrationTests
condition: always()
variables:
INTEGRATION_TEST_RUN_ID: $[ dependencies.Build.outputs['CreateTestRun.INTEGRATION_TEST_RUN_ID'] ]
steps:
- checkout: none
- powershell: |
$url = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/test/runs/$($env:INTEGRATION_TEST_RUN_ID)?api-version=5.0"
Write-Host "URL: $url"
$body = @{
"state" = "Completed"
}
$json = $body | ConvertTo-Json
Invoke-RestMethod -Method 'Patch' -Uri $url -Body $json -ContentType 'application/json' -Headers @{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}
displayName: 'Complete test run'
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
请注意,此作业需要显式依赖Build,以便我可以读取输出变量INTEGRATION_TEST_RUN_ID,并且它显然依赖于IntegrationTests,因此在所有测试完成之前它不会完成测试运行完成了。
【问题讨论】:
标签: azure-devops azure-pipelines tfvc appveyor