使用 API 以编程方式在 Azure DevOps Pipeline 中添加和更新测试

Adding and updating tests within Azure DevOps Pipeline programmatically using API

我正在将我们的一个项目转换为使用 Azure DevOps 而不是 CI 的 AppVeyor。作为构建的一部分,我们使用自定义测试 运行ner 来执行某些测试。

当在 AppVeyor 中 运行ning 时,我们直接从测试 运行 中调用 REST API 来通知构建服务器测试 运行 并更新他们的地位。这非常简单,如他们 Add Tests and Update Tests 文档的 REST 部分所示,并让我们很好地集成到 AppVeyor 的 UI.

我一直在研究如何在 Azure DevOps 中做同样的事情。我找到了 adding and updating 测试结果的 REST API 部分。 API 文档中并没有完全清楚这是我在 运行ning 管道中使用的内容,还是用于其他一些场景。我已经搜索过其他人试图做同样的事情,但到目前为止没有任何运气。大多数示例都谈到了上传测试结果文件,但这似乎是一种相当间接的发布测试结果的方式,特别是因为我想在 运行 之前注册所有测试,然后更新它们的状态完成。

是否有人对在构建期间使用 Azure DevOps API 发布测试结果有任何建议或示例?


详细解决方法:

有了 Merlin Liang 的指导回答,我现在已经开始工作了。

步骤 1. 首先,我创建了一个新测试 运行,这是我在构建作业(称为 Build)结束时使用的powershell 脚本:

  - 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 以确保测试在 运行ning.

时显示在构建的测试列表中

第 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
    ...

我的测试 运行ner(用 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"

其中那些class成员变量只是从通常的环境变量中读取的,而testResultId是我最初POST测试时API返回的ID .

同样,当我从 Azure Pipeline YAML 调用测试 运行ner 并在授权中使用它时,我在 env 部分明确设置了 SYSTEM_ACCESSTOKEN header.

步骤 3. 最后,我 fan-in 再次将测试 运行 标记为在依赖于集成测试作业的专用作业中完成并且必须始终运行 即使测试失败:

  - 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 因此无法完成测试 运行 直到所有测试都完成。

你已经很接近答案了。请参阅此文档:Surface test results in the Tests tab.

除了通过任务上传测试结果,比如Publish Test Results任务,VS测试等。我们还提供了一种通过Rest api上传结果的方法:

要实现您想要的效果,您必须首先使用一个已知的内部版本号创建测试 运行,然后 post 测试结果。

  1. Create 对现有构建的新测试,在请求正文中指定 buildID

样本:

POST https://dev.azure.com/{org name}/{project}/_apis/test/Runs/{runId}/results?api-version=5.0

{
 "name": "NewTest", 
 "build": { "id": "162" }, 
 "isAutomated": true, 
 "state": "Waiting" 
}
  1. 运行测试,以便测试结果可用。

  2. 现在,post这个新的测试结果进入之前创建的测试。

[ { "testCaseTitle": "ReferBuild", "automatedTestName": "ReferBuildAuto", "priority": 1, "outcome": "Passed" }]

这里可以参考doc中的例子。

  1. 终于可以使用update api.