如何配置AppVeyor,使OpenCover+xUnit测试失败时构建失败
我之前也碰到过一模一样的情况,折腾了好一阵才搞定。核心问题是OpenCover默认不会把xUnit的测试失败返回码传递给AppVeyor,哪怕你加了-returntargetcode,也可能因为参数位置不对或者脚本逻辑没处理到位而失效。下面是几个关键的解决步骤:
1. 确保-returntargetcode参数的正确使用
这个参数是OpenCover自己的参数,必须放在OpenCover.Console.exe的参数列表里,而不是传给xUnit的-targetargs里。正确的命令格式应该是这样的:
OpenCover.Console.exe -returntargetcode -target:"xunit.console.exe" -targetargs:"YourTestAssembly.dll -noshadow" -output:coverage.xml
这个参数的作用是让OpenCover把目标程序(也就是xUnit控制台)的退出码作为自己的退出码返回,这样AppVeyor才能捕获到测试失败的信号。
2. 在AppVeyor脚本中显式检查退出码
有时候即使OpenCover返回了非0码,脚本如果没有显式处理,AppVeyor可能不会终止构建。比如在PowerShell脚本里,你需要手动检查$LASTEXITCODE:
# 运行OpenCover+xUnit & OpenCover.Console.exe -returntargetcode -target:"xunit.console.exe" -targetargs:"Tests\bin\Release\YourTests.dll -noshadow" -output:coverage.xml # 检查测试是否失败 if ($LASTEXITCODE -ne 0) { Write-Error "测试执行失败,退出码: $LASTEXITCODE" exit 1 } # 只有测试成功时才上传覆盖率到Coveralls & Coveralls.Net.exe --opencover coverage.xml
如果是CMD脚本,就用%errorlevel%来检查:
OpenCover.Console.exe -returntargetcode -target:"xunit.console.exe" -targetargs:"Tests\bin\Release\YourTests.dll -noshadow" -output:coverage.xml if %errorlevel% neq 0 exit /b %errorlevel% Coveralls.Net.exe --opencover coverage.xml
3. 排除Coveralls.Net的干扰
注意:即使测试失败,Coveralls.Net的上传命令可能还是会返回0,导致AppVeyor误以为整个构建成功。所以一定要确保只有测试通过时才执行覆盖率上传步骤,也就是把上传命令放在测试成功的分支里,就像上面的脚本示例那样。
4. 验证xUnit本身的退出码
先单独运行xUnit控制台程序,确认测试失败时它会返回非0的退出码:
xunit.console.exe YourTestAssembly.dll
如果测试失败后xUnit返回的是0,那问题出在xUnit本身,你需要检查xUnit的版本(xUnit 2.x及以上版本才会在测试失败时返回非0码),或者测试项目的配置是否有问题。
按照这几步调整后,AppVeyor应该就能在测试失败时正确终止构建了。
内容的提问来源于stack exchange,提问作者Philip Pittle

