如果未运行测试,则使TeamCity构建失败

本文关键字:TeamCity 构建 失败 则使 运行测试 如果 | 更新日期: 2023-09-27 18:26:39

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

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

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

我该如何做到这一点?

如果未运行测试,则使TeamCity构建失败

您可以在度量更改时添加构建失败条件(请参阅构建配置管理区域的构建失败条件步骤)。有一个度量标准叫做"测试次数"。将其设置为0,以在未运行测试的情况下使生成失败。

我看了一下您引用的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,而不是尝试接球。当然,你不应该真的抛出Exception,但这是偏离主题的。