AppVeyor + OpenCover + xUnit - 测试失败时构建不会失败

AppVeyor + OpenCover + xUnit - Build doesn't fail when tests fail

我创建了一个 AppVeyor Build Script,它使用 OpenCover 和 Coveralls.Net 来 运行 我的 xUnit 测试,并将代码覆盖率发布到 Coveralls.io。

但是当我的测试失败时 - AppVeyor 报告 build successful如果 OpenCover + xUnit 报告测试失败,我该如何配置 AppVeyor 失败?

脚本基于csMACnz's sample:

.\src\packages\OpenCover.4.6.519\tools\OpenCover.Console.exe 
   -register:user 
   -target:"xunit.console.clr4.exe"  
   "-targetargs:""src\HttpWebRequestWrapper.Tests\bin$env:CONFIGURATION\HttpWebRequestWrapper.Tests.dll"" 
   /noshadow 
   /appveyor" 
   -filter:"+[HttpWebRequestWrapper*]*" 
   -output:opencoverCoverage.xml

    $coveralls = (Resolve-Path "src/packages/coveralls.net.*/tools/csmacnz.coveralls.exe").ToString()
    & $coveralls --opencover -i opencoverCoverage.xml --repoToken $env:COVERALLS_REPO_TOKEN --commitId $env:APPVEYOR_REPO_COMMIT --commitBranch $env:APPVEYOR_REPO_BRANCH --commitAuthor $env:APPVEYOR_REPO_COMMIT_AUTHOR --commitEmail $env:APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL --commitMessage $env:APPVEYOR_REPO_COMMIT_MESSAGE --jobId $env:APPVEYOR_JOB_ID

我已经尝试将 -returntargetcode 标志添加到 OpenCover.Console.exe 代码中,但这似乎并不表示 AppVeyor 构建失败。

我觉得原因很简单。按照您编写 YML 文件的方式,AppVeyor 期望整个 test_script 提供非零 return 代码,而您留下的 PowerShell 脚本部分内的故障不会导致这种情况。

您必须 运行 分别执行每个命令,然后任何失败都会导致整个构建失败,因为 my AppVeyor script shows

test_script:
  - dotnet test Tests\CSharpCore\Tests.NetStandard.csproj --configuration Release --no-build --filter "FullyQualifiedName~Lextm.SharpSnmpLib.Integration.TrapDaemonTestFixture"
  - dotnet test Tests\CSharpCore\Tests.NetStandard.csproj --configuration Release --no-build --filter "FullyQualifiedName~Lextm.SharpSnmpLib.Integration.DaemonTestFixture"
  - dotnet test Tests\CSharpCore\Tests.NetStandard.csproj --configuration Release --no-build --filter "FullyQualifiedName~Lextm.SharpSnmpLib.Unit"

如果我将这三个命令包装在批处理文件或 PowerShell 脚本中,我可以重现您遇到的相同问题。

同意 Lee 的观点,但更简单的选择是在脚本开头添加 $ErrorActionPreference = "Stop"。

看看你对下面 post 的评论,你需要执行所有命令,即使出现问题也是如此。我这个案例看ErrorVariable。好的讨论和示例是 here

看起来有几种方法可以从 AppVeyor 中获得所需的行为。我最终使用了 AppVeyor Discussion Thread @ilyaf 中引用的 $LastExitCode

这种方法最终给了我更多的灵活性 - 我可以继续 运行 我的整个测试脚本,但如果任何特定部分失败,测试步骤仍然失败:

.\src\packages\OpenCover.4.6.519\tools\OpenCover.Console.exe 
  -register:user 
  -target:"xunit.console.clr4.exe"  
  "-targetargs:""src\HttpWebRequestWrapper.Tests\bin$env:CONFIGURATION\HttpWebRequestWrapper.Tests.dll"" 
  /noshadow 
  /appveyor" 
  -filter:"+[HttpWebRequestWrapper*]*" 
  -output:opencoverCoverage.xml

$testRunnerErrorCode = $LastExitCode

#can move this to end of script if I want to still publish code coverage
#for failed tests
if ($testRunnerErrorCode -ne 0){
   throw "xUnit failed with code $testRunnerErrorCode "
}


$coveralls = (Resolve-Path "src/packages/coveralls.net.*/tools/csmacnz.coveralls.exe").ToString()
& $coveralls --opencover -i opencoverCoverage.xml --repoToken  $env:COVERALLS_REPO_TOKEN --commitId $env:APPVEYOR_REPO_COMMIT --commitBranch $env:APPVEYOR_REPO_BRANCH --commitAuthor $env:APPVEYOR_REPO_COMMIT_AUTHOR --commitEmail $env:APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL --commitMessage $env:APPVEYOR_REPO_COMMIT_MESSAGE --jobId $env:APPVEYOR_JOB_ID

我要将 Lex 的回答标记为正确,因为它是对问题最直截了当的回答。