【发布时间】:2020-12-12 20:31:02
【问题描述】:
我正在尝试在 MS Azure devops 管道中定义的测试项目上运行 dotnet test 命令。
这是有效的:
- script: |
dotnet test "./Project One/Project One Unit Tests.fsproj" -c Release --no-build --filter "TestCategory!=SKIP_ON_DEPLOY & TestCategory!=REQUIRES_API_KEY"
dotnet test "./Project Two/Project Two Unit Tests.fsproj" -c Release --no-build --filter "TestCategory!=SKIP_ON_DEPLOY & TestCategory!=REQUIRES_API_KEY"
displayName: 'run tests in cascade'
我不想指定项目名称,只指定一些规则(项目名称必须以“UnitTests”、“Unit Tests”或“Unit_Tests”结尾)但dotnet test <PROJECT> 不允许使用通配符。
似乎通配符适用于 dotnet test <DLL> (./**/*Unit?Tests.dll) 但它失败了,因为它在 obj 文件夹中找不到 deps.json 文件。
我的解决方案是循环通过过滤的项目文件列表:
for proj in ./**/*Unit?Tests.*proj
do
dotnet test "$proj" -c Release --no-build --filter "TestCategory!=SKIP_ON_DEPLOY & TestCategory!=REQUIRES_API_KEY"
done
它正在运行测试,但与级联调用不同,这里当项目测试失败时,它不会使步骤失败,因此管道不会停止!
我试图从运行中获取结果,但没有成功(这不起作用):
for proj in ./**/*Unit?Tests.*proj
do
result=$(dotnet test "$proj" -c Release --no-build --filter "TestCategory!=SKIP_ON_DEPLOY & TestCategory!=REQUIRES_API_KEY")
if result = 1
then
exit 1
fi
done
有什么建议吗?
为什么当 dotnet test 失败(退出 1)时,该步骤不会失败?
我试图只将失败的测试项目放入循环中,但在这种情况下它会失败。
[更新]
完整的 pipeline.yaml:
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
variables:
project file: "Alex75.MySolution/Alex75.MyProject.fsproj"
steps:
- script: dotnet build -c Release
displayName: 'Build'
- script: |
dotnet test "./ProjectTwo Unit Tests/ProjectTwo Unit Tests.fsproj" -c Release --no-build --filter "TestCategory!=SKIP_ON_DEPLOY & TestCategory!=REQUIRES_API_KEY"
dotnet test "./ProjectOne Tests/ProjectOne Unit Tests.fsproj" -c Release --no-build --filter "TestCategory!=SKIP_ON_DEPLOY & TestCategory!=REQUIRES_API_KEY"
displayName: 'Test'
condition: false
- script: |
for proj in ./**/*Unit?Tests.*proj
do
echo "run tests in $proj"
dotnet test "$proj" -c Release --no-build --filter "TestCategory!=SKIP_ON_DEPLOY & TestCategory!=REQUIRES_API_KEY"
done
displayName: 'Test (Unit Test projects)'
condition: true
- 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."
displayName: 'Check tests result'
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 不可用,因此请求获取 logs 集合,然后请求获取特定的最后一个日志(响应似乎按日期排序,也许是值得仔细检查)。
请注意,如果第二个请求返回 404、500 或其他结果(不是失败),错误检查将不会发现最终错误!需要对响应进行适当的检查。
我在 PowerShell 中测试了 -match "Failed!" 但我还没有在管道中测试 throw 命令,因为...
dotnet test 循环中的命令正在运行!
在花了这么多时间试图弄清楚如何阅读和检查日志之后,我发现了一个单独的 PowerShell 脚本,我发现最初的简单解决方案有效!
是的,构建失败是因为测试失败(它还显示了指向问题的精确错误)并且步骤失败了。
(所以下一步,检查测试结果,被跳过了!)
我认为我应该在过滤测试项目之前犯一些错误,以便失败的项目没有运行(并且没有引发任何错误)所以我认为它没有“拦截”错误,并且构建没有停下来。
可能是我在更改时混合了 2 个不同的管道文件。
无论如何,这是有罪的步骤(脚本):
for proj in ./**/*Unit?Tests.*proj
do
echo "run tests in $proj"
dotnet test "$proj" -c Release --no-build --filter "TestCategory!=SKIP_ON_DEPLOY & TestCategory!=REQUIRES_API_KEY"
done
在带有 echo 的列表中,可以查看使用了哪些测试项目。
【问题讨论】:
-
您好,刚刚检查一下这个问题现在是否仍然阻碍您?这个问题有更新吗?
-
老实说,我仍然在寻找更简单的东西,但我肯定会在几天内看看。谢谢。
标签: bash .net-core azure-devops