0

我们有一个设置,TeamCity 在其中构建软件并在其上运行单元测试。我们使用受此答案启发的 powershell 脚本,它使用 vstest 运行单元测试并使用 dotcover 报告代码覆盖率。

有时,开发人员所做的更改会导致脚本根本无法运行测试。TeamCity 没有使构建失败,而是将构建报告为成功,但没有提及测试(因为它们没有运行)。

如果未运行测试,我希望构建失败。

我该如何做到这一点?

4

2 回答 2

3

您可以在指标更改时添加构建失败条件(请参阅构建配置管理区域的构建失败条件步骤)。有一个称为“测试次数”的指标。将其设置为 0,如果没有运行测试,则构建失败。

于 2013-08-07T19:06:25.827 回答
1

我查看了您引用的 powershell 脚本。我看到了测试可能无法运行的两个明显原因:

# Get list of folders with Test DLLs in them matching pattern *Tests\bin
$testFolders = Get-ChildItem -Recurse -Force $rootDirectory | 
  Where-Object { ($_.PSIsContainer -eq $true) -and (($_.FullName -like "*Tests\bin\" + $vsConfigName) -or ($_.FullName -like "*Tests\bin\x64\" + $vsConfigName)) }

如果没有文件夹与此 gci 中的模式匹配,则不会运行任何测试。

#grab the testing DLLs from the folder which match pattern *Tests.dll
$testDlls = Get-ChildItem -Force $folder.FullName -File |
  Where-Object { $_.Name -like "*Tests.dll" }

同样,如果没有 dll 与模式匹配,则不会运行测试。

除此之外,脚本真的应该有一个 try catch,如果你没有找到任何测试文件夹或任何测试 dll,你可以抛出。我已经编辑了您引用的代码示例以显示这一点:

#rootDirectory is the base directory to search for Test Projects. (Most likely your solution directory)
#configName is a string name that the code coverage output files will be placed in
#filters is a list of dotCover filters to be added to the /Filters argument
#vsConfigName is the configuration folder to find the Test DLLs in
Param([string]$rootDirectory,[string]$configName,[string]$filters,[string]$vsConfigName)

$vstestconsolepath = "C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe"
$dotcoverpath = "C:\BuildAgent\tools\dotCover\dotCover.exe"
$dotcovertargetexecutable = "/TargetExecutable=" + $vstestconsolepath
$dotcoveroutput = "/Output=" + $configName + "/coverage.dcvr"
$dotcoverfilters = "/Filters=" + $filters

try
{
  # Get list of folders with Test DLLs in them matching pattern *Tests\bin
  $testFolders = Get-ChildItem -Recurse -Force $rootDirectory | Where-Object { ($_.PSIsContainer -eq $true) -and (($_.FullName -like "*Tests\bin\" + $vsConfigName) -or ($_.FullName -like "*Tests\bin\x64\" + $vsConfigName)) } | Select-Object
  if ($testFolder -eq $null) 
  {
    throw [Exception] "No test folders found."
  }

  foreach ($folder in $testFolders)
  {
      #look for Fakes DLLs. If we find one we can't do code coverage on this test assembly
      $fakesDLLs = Get-ChildItem -Recurse -Force $folder.FullName -File | Where-Object { $_.Name -like "*Fakes.dll" } | Select-Object

      #grab the testing DLLs from the folder which match pattern *Tests.dll
      $testDlls = Get-ChildItem -Force $folder.FullName -File | Where-Object { $_.Name -like "*Tests.dll" } | Select-Object

      foreach ($dll in $testDlls)
      {
          if ($fakesDLLs.length -eq 0)
          {
              $arr += @($dll.FullName)
          }
          else
          {
              $fakesArr += @($dll.FullName)
          }
      }
  }

  if ($arr -eq $null) 
  {
    throw [Exception] "No test dlls found."
  }

...

}
catch [Exception]
{
  Write-Host($_.Exception.GetType().FullName)
  Write-Host($_.Exception.Message)
  Write-Host($_.Exception.StackTrace)
  exit 1
}

当然你不一定需要走那么远,你可以exit 1而不是用 try catch 扔。当然,你不应该真的扔Exception,但那是题外话。

于 2013-08-07T11:49:36.623 回答