【问题标题】:How can we read the Azure DevOps task log?我们如何阅读 Azure DevOps 任务日志?
【发布时间】:2020-06-28 10:50:14
【问题描述】:

我在 azure 管道中有一项任务,该任务执行一些动态测试,但由于测试数量众多,单个测试是否通过或失败取决于日志中的内容。

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

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

说明:根据需要

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

【问题讨论】:

  • 它们是单元测试吗?如果他们失败了,他们应该会失败。

标签: azure-devops azure-pipelines azure-devops-rest-api


【解决方案1】:

如果您无法通过标准错误使管道失败,您可以使用Builds - Get Build Log 调查任务并根据结果设置一个变量,在其他任务中,使用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!"
}

(可以通过APIBuilds - Get Build Logs获取日志id)

【讨论】:

    【解决方案2】:

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

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

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

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

    evaluate-test-results.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 任务:

    # 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 任务来解释测试结果。相应地设置您的测试框架/工具和测试结果文件。一定要设置failTaskOnFailedTests: true

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

    【讨论】:

    • @Pukli Balazs - 我已经编辑了问题并给出了更多说明。问题是您要设置的标志,我没有办法,只能读取日志并设置它。所以我在问是否有一个标准的任务日志读取机制可以用来查找表达式。
    • @userx ,感谢您的澄清!我在回答中为您创建了“备选方案 1”部分。如果您有任何其他问题,请告诉我!
    猜你喜欢
    • 1970-01-01
    • 2020-08-16
    • 2019-11-28
    • 1970-01-01
    • 2010-10-07
    • 2011-09-24
    • 2019-05-06
    • 1970-01-01
    • 2012-08-08
    相关资源
    最近更新 更多