azure devops pipeline | bash脚本,用于在多个项目上运行dotnet测试

azure devops pipeline | bash脚本,用于在多个项目上运行dotnet测试,bash,.net-core,azure-devops,Bash,.net Core,Azure Devops,我正在尝试对MS Azure devops管道中定义的测试项目运行dotnet test命令 这是有效的: -脚本:| dotnet测试“/Project One/Project One Unit Tests.fsproj”-c发行版--无构建--筛选“TestCategory!=跳过部署和测试类别!=需要API密钥” dotnet测试“/Project Two/Project Two Unit Tests.fsproj”-c发行版--无构建--筛选“TestCategory!=跳过部署和测试类

我正在尝试对MS Azure devops管道中定义的测试项目运行
dotnet test
命令

这是有效的:

-脚本:|
dotnet测试“/Project One/Project One Unit Tests.fsproj”-c发行版--无构建--筛选“TestCategory!=跳过部署和测试类别!=需要API密钥”
dotnet测试“/Project Two/Project Two Unit Tests.fsproj”-c发行版--无构建--筛选“TestCategory!=跳过部署和测试类别!=需要API密钥”
displayName:“在级联中运行测试”
我不想指定项目名称,只有一些规则(项目名称必须以“UnitTests”、“UnitTests”或“Unit_Tests”结尾),但是
dotnet test
不允许使用通配符。 通配符似乎适用于
dotnet test
(../***Unit?Tests.dll),但它失败了,因为它在obj文件夹中找不到deps.json文件

我的解决方案是通过项目文件的筛选列表循环:

用于./***单元测试中的项目。*项目
做
dotnet测试“$proj”-c发行版--无构建--筛选“TestCategory!=跳过部署和测试类别!=需要API密钥”
完成
它正在运行测试,但与级联调用不同,在这里,当项目测试失败时,它不会使步骤失败,因此管道不会停止

我试图从运行中获得结果,但未成功(这不起作用):

用于./***单元测试中的项目。*项目
做
结果=$(dotnet测试“$proj”-c发行版--无构建--筛选“TestCategory!=跳过部署和测试类别上的测试!=需要API\U密钥”)
如果结果=1
然后
出口1
fi
完成
有什么建议吗? 为什么
dotnet测试失败(退出1)时,步骤没有失败?
我试图只将失败的测试项目放入循环中,但在这种情况下失败了

[更新]
完整管道.yaml:

触发器:
-主人
游泳池:
vmImage:“ubuntu最新版本”
变量:
项目文件:“Alex75.MySolution/Alex75.MyProject.fsproj”
步骤:
-脚本:dotnetbuild-c发行版
displayName:“生成”
-脚本:|
dotnet测试“/ProjectTwo-unittests/ProjectTwo-unittests.fsproj”-c发行版--无构建--筛选“TestCategory!=跳过部署和测试类别!=需要API密钥”
dotnet测试“/ProjectOne测试/ProjectOne单元测试.fsproj”-c发行版--无构建--筛选“TestCategory!=跳过部署和测试类别!=需要API密钥”
displayName:“测试”
条件:假
-文字:|
对于/***单元测试中的项目。*项目
做
echo“在$proj中运行测试”
dotnet测试“$proj”-c发行版--无构建--筛选“TestCategory!=跳过部署和测试类别!=需要API密钥”
完成
displayName:'测试(单元测试项目)'
条件:正确
-powershell:|
$URL=“$(System.CollectionUri)/$(System.TeamProject)/\u api/build/builds/$(build.BuildId)/logs?api版本=5.1”
写入主机“URL=$URL”
$logs=Invoke RestMethod-Uri$URL-Headers@{authorization=“Basic$(PAT)”}-Method Get
$lastLogId=$Logs.value[$Logs.value.count-1].id
写入主机“lastLogId=$lastLogId”
$URL=“$(System.CollectionUri)/$(System.TeamProject)/\u api/build/builds/$(build.BuildId)/logs/$lastLogId?api版本=5.1”
$result=Invoke RestMethod-Uri$URL-Headers@{authorization=“Basic$(PAT)”}-Method Get
写入主机$result
写入主机“开始检查结果…”
$lines=$result.Split([Environment]::NewLine)
foreach($行中的行){
如果($line-match“Failed!”)
{
抛出“dotnet测试失败($line)”
}
}
写入主机“测试结果检查已完成”
displayName:“检查测试结果”
PowerShell脚本 使用@vito liu msft的例子,我试图检查测试日志以检查错误

此处仅显示powershell脚本:

$URL = "$(System.CollectionUri)/$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/logs?api-version=5.1"
Write-Host "URL = $URL"
  
$logs = Invoke-RestMethod -Uri $URL -Headers @{authorization = "Basic $(PAT)"} -Method Get 
$lastLogId = $Logs.value[$Logs.value.count-1].id
Write-Host "lastLogId = $lastLogId"  

$URL = "$(System.CollectionUri)/$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/logs/$lastLogId?api-version=5.1"
$result = Invoke-RestMethod -Uri $URL -Headers @{authorization = "Basic $(PAT)"} -Method Get 
Write-Host $result

Write-Host "Start Check result..."

$lines = $result.Split([Environment]::NewLine)
foreach($line in $lines) {
    if($line -match "Failed!")
    {
        throw 'dotnet test fails ($line)'
    }
}

Write-Host "Test result check completed."
PAT是创建时的个人访问令牌,无需转换 在HTTP请求中使用它之前。
LogId不可用,因此有一个获取日志集合的请求,而不是第二个获取特定最后一个日志的请求(响应似乎按日期排序,可能值得仔细检查)

请注意,如果第二个请求返回404、500或其他结果(不是失败),错误检查将不会找到实际错误!需要对响应进行适当检查

我在PowerShell中测试了-match“Failed!”,但没有在管道中测试throw命令,因为

循环中的dotnet测试命令正在工作! 在花了这么多时间试图弄清楚如何读取和检查日志后,抛出一个单独的PowerShell脚本,我发现最初的简单解决方案是可行的
是的,构建失败是因为测试失败(它还显示了指向问题的精确错误),步骤失败。
(因此,将跳过下一步,即检查测试结果!)

我认为我应该在筛选测试项目之前犯一些错误,这样失败的项目就不会运行(也不会引发任何错误),所以我认为它没有“拦截”错误,构建也没有停止。
可能是我在更改管道时混合了两个不同的管道文件

无论如何,这是被指控的步骤(脚本):

用于./***单元测试中的项目。*项目
做
echo“在$proj中运行测试”
dotnet测试“$proj”-c发行版--无构建--筛选“TestCategory!=跳过部署和测试类别!=需要API密钥”
完成
在带有echo的列表中,可以看到使用了哪些测试项目

当项目测试失败时,它不会使步骤失败,因此管道不会停止! 为什么当dotnet测试失败(退出1)时,步骤没有失败

作为一种解决方法,我们可以通过此获取
dotnet测试
任务日志id,添加任务
powershell
,然后输入下面的脚本来分析
dotnet测试
日志。我们需要重新开始
$connectionToken="{PAT}"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
$URL = "https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}/logs/{logId}?api-version=6.1-preview.2"
$Result = Invoke-RestMethod -Uri $URL -Headers @{authorization = "Basic $base64AuthInfo"} -Method Get 
Write-Host $result
$lines = $result.Split([Environment]::NewLine)

        $passed = 0;
        $failed = 0;

        foreach($line in $lines) {
            if ($line -match "{match sentence}") { 
              throw 'dotnet test fails (exit 1)'

            }
        }
GET https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}/logs?api-version=6.1-preview.2