我们如何阅读 Azure DevOps 任务日志?

How can we read the Azure DevOps task log?

我在 Azure 管道中有一项任务执行一些动态测试,但由于测试的数量很多,因此无论单个测试通过还是失败,都取决于日志中的内容。

因此,Azure DevOps 步骤始终变为绿色。我希望通过阅读该日志然后根据日志是否包含故障来决定下一步做什么来解决问题。假设,如果任务变为绿色并且日志检测到失败,我将决定不发布工件。

如何通过在下一个任务中使用标准 azure api 读取上一个任务的日志,然后做出决定,以标准的方式解决这个问题?

说明:根据需要

这些测试不是单元,它们实际上是一些自定义 java 测试,通过从 linux 机器上的自托管代理调用 .sh 文件来触发。

编辑:经过澄清,我将我的评论分为两部分:您的自定义测试用例,然后是我之前在此处发表的评论的其余部分,适用于使用标准单元测试框架的情况。

备选方案 1:自定义测试的解决方案可能性,基于分析测试日志文件

首先你需要一个脚本,例如解释日志文件的 PowerShell 脚本,确定测试是否失败,并相应地设置 vso task.complete 结果 属性(参见下面的示例)。

我们称这个文件为 evaluate-test-results.ps1,假设它解释某种 testResults.json 数据,包含一个名为 haveTestsPassed 的重要 属性,决定是否通过的测试:

评估测试结果。ps1 文件内容:

<#
.SYNOPSIS
Checks test results.
#>

param (
    [Parameter(Mandatory = $true)]
    [string]$testResultsJson
)

try {
    $testResults = $testResultsJson | ConvertFrom-Json

    if($testResults.haveTestsPassed)
    {
       Write-Host "##vso[task.complete result=Succeeded;]Tests have successfully passed"
    }
    else
    {
       Write-Host "##vso[task.complete result=Failed;]Tests have NOT passed"
    }
}
catch {
    Write-Host "##vso[task.complete result=Failed;]Error while parsing test results from JSON log file..."
}

然后,您可以在 PowerShell@2 任务中使用此脚本,如下所示:

- task: PowerShell@2
  displayName: "PowerShell: Evaluate test results from testResults.json"
  inputs:
    targetType: filePath
    filePath: 'evaluate-test-results.ps1'
    arguments: "-testResultsJson 'testResults.json'"
    failOnStderr: true

注:

你也可以在 haveTestsPassed 为 false 时抛出标准错误,或者,感谢 failOnStderr 属性。不过上面这个解决方案比较官方一点

备选方案 2:标准单元测试框架的解决方案可能性

如果 dotnet test 命令配置为 运行 你的测试

,则解决方案更简单

简单的解决方案就是这样,如果您的测试绑定到 dotnet test 命令,例如使用 xUnit。在这种情况下,如果您的单元测试之一失败,则默认情况下此任务将失败,而无需 PublishTestResults@2 task:

# This task will run the 'dotnet test' command, as if you would from a CLI
- task: DotNetCoreCLI@2
  displayName: Run and publish tests
  inputs:
    command: 'test'

如果不能使用dotnet test命令

在这种情况下,您必须使用 PublishTestResults@2 任务来解释测试结果。相应地设置您的测试 framework/tool 和测试结果文件。一定要设置failTaskOnFailedTests: true

- task: PublishTestResults@2
  inputs:
    testRunner: VSTest # or else...
    testResultsFiles: '**/*.trx' # or else...
    failTaskOnFailedTests: true

如果您无法通过标准错误使管道失败,您可以将 Builds - Get Build Log to investigate the task and according to the results set a variable, in the other tasks, uses custom conditions 与此变量一起使用,或者让所有管道都失败。

所以,一个类似这样的 PowerShell 脚本:

$token = "YOUR-PAT"
Base64-encodes the Personal Access Token (PAT) appropriately
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
 
# Construct the REST URL to obtain Build ID
$uri = "$(System.TeamFoundationCollectionUri)/$(System.TeamProject)/_apis/build/builds/logs/{logId}?api-version=5.1"
 
# Invoke the REST call and capture the results
$log= Invoke-RestMethod -Uri $uri -Method Get -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}

if($log -match "some error")
{
    # Option 1: set a variable
    Write-Host "##vso[task.setvariable variable=testsStatus]failed"
    # Now in the artifacts task use custom condition:
    # and(succeeded(), ne(variables['testsStatus'], 'failed'))

    # Option 1: fail the pipeline
    Write-Error "The tests not passed!"
}

(您可以通过 API Builds - Get Build Logs 获取日志 ID)