【问题标题】:VStest code coverage report in jenkinsjenkins 中的 VStest 代码覆盖率报告
【发布时间】:2015-05-13 12:50:09
【问题描述】:

我正在使用 Jenkins 为 .Net 项目设置 CI。

我使用 MSTest 插件和 VStestrunner 插件来运行测试。 现在我有 .trx 文件和 .Coverage 文件 我在显示代码覆盖率报告时遇到问题

如果你知道任何插件可以做到这一点,请帮助我。

【问题讨论】:

  • 如果您找到任何解决方案,请发布结果

标签: jenkins continuous-integration mstest jenkins-plugins vstest


【解决方案1】:

我为此苦苦挣扎了很久,终于发现我们可以使用“CodeCoverage.exe”“ReportGenarator.exe”和“Cobertura plugin”来显示完美的覆盖率报告。

“ReportGenerator.exe”可以从https://github.com/danielpalme/ReportGenerator/releases获取

  • 首先使用“CodeCoverage.exe”将.coverage文件翻译成.xml文件
    "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Team Tools\Dynamic Code Coverage Tools\CodeCoverage.exe" analyze -output:./TestResults/coverage.xml ./TestResults/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.coverage"
  • 第二次使用 ReportGenerator.exe 将 vstest xml 格式转换为 Cobertura xml 格式
    "ReportGenerator_4.4.7\net47\ReportGenerator.exe" -reports:./TestResults/coverage.xml -targetdir:./TestResults -reporttypes:cobertura
  • 最后安装cobertura插件用它来收集xml文件,这里给出一个管道使用示例
    post {
        always {
            cobertura coberturaReportFile: './TestResults/Cobertura.xml'
        }
    }
  • 结果就是这样

【讨论】:

  • 你能说出下面命令中的 gtest-coverage.xml 是什么吗 - "ReportGenerator_4.4.7\net47\ReportGenerator.exe" -reports:./TestResults/gtest-coverage.xml -targetdir:./TestResults -reporttypes:cobertura
  • @Dhiraj 对不起,我犯了一个错误,现在我已经修复了。
  • 只需添加一个反向链接,您就可以使用此技术为 Azure Pipelines 代码覆盖报告生成与 Cobertura 兼容的输出:github.com/microsoft/azure-pipelines-tasks/issues/5562
【解决方案2】:

要显示覆盖率报告,您需要将其转换为 XML 格式并使用 MSTest 插件发布报告。 MSTest Plugin 建议 (https://wiki.jenkins-ci.org/display/JENKINS/MSTest+Plugin) 使用第三方应用程序转换为 XML 格式和 powershell(您需要为其安装 pugin)来运行它。

但是,您只能使用 PowerShell 进行转换。有脚本示例:

$coverageFile = $(get-ChildItem -Path .\TestResults -Recurse -Include *coverage)[0]
$xmlCoverageFile = ".\TestResults\vstest.coveragexml"

Add-Type -path "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\PrivateAssemblies\Microsoft.VisualStudio.Coverage.Analysis.dll"

[string[]] $executablePaths = @($coverageFile)
[string[]] $symbolPaths = @()

$info = [Microsoft.VisualStudio.Coverage.Analysis.CoverageInfo]::CreateFromFile($coverageFile, $executablePaths, $symbolPaths);
$data = $info.BuildDataSet()

$data.WriteXml($xmlCoverageFile)

您可能需要根据您的 VS 版本修复 Microsoft.VisualStudio.Coverage.Analysis.dll 的路径。

【讨论】:

    【解决方案3】:

    在 ghking 的回答之后,cobertura 抱怨说虽然 xml 在磁盘上,但没有找到它。我必须从路径中删除“./”,以便 cobertura 能够找到该文件。

       post {
           always {
               cobertura coberturaReportFile: 'TestResults/Cobertura.xml'
           }
       }
    

    【讨论】:

      【解决方案4】:

      执行此操作的完整脚本是:

      <#
      .SYNOPSIS
          Script to convert code coverage report into xml format that can then be published by external tools.
      
      .DESCRIPTION
          Covering code coverage statistics as part of quality improvement initiatives.    
      #>
      Param(
          [String] $InputCoveragePath =@("..\GeneratedFiles\Docs\Reports"),
          [String] $OutputCoverageFileExtension =@(".coveragexml"),
          [String] $CoverageAnalysisAssembly =@("Microsoft.VisualStudio.Coverage.Analysis.dll"),
          [String[]] $ExecutablePaths =@(""),
          [String[]] $SymbolPaths =@("")
      )
          $ScriptLocation = Split-Path $script:MyInvocation.MyCommand.Path -Parent
          Write-Host $ScriptLocation
      
      $RunAs32Bit = {
          Param(
              [String] $InputCoveragePath =@("..\GeneratedFiles\Docs\Reports"),
              [String] $OutputCoverageFileExtension =@(".coveragexml"),
              [String] $CoverageAnalysisAssembly =@("Microsoft.VisualStudio.Coverage.Analysis.dll"),
              [String[]] $ExecutablePaths =@(""),
              [String[]] $SymbolPaths =@(""),
              [String] $ScriptLocation =@(".")
          )
          Write-Host "[CoverageConverter][Begin]: Coverage conversion started..."
      
          Write-Host "[CoverageConverter][InputCoveragePath]: $InputCoveragePath"
          Write-Host "[CoverageConverter][OutputCoverageFileExtension]: $OutputCoverageFileExtension"
          Write-Host "[CoverageConverter][CoverageAnalysisAssembly]: $CoverageAnalysisAssembly"
          Write-Host "[CoverageConverter][ExecutablePaths]: $ExecutablePaths"
          Write-Host "[CoverageConverter][SymbolPaths]: $SymbolPaths"
          Write-Host "[CoverageConverter][ScriptLocation]: $ScriptLocation"
          
          Add-Type -path "$CoverageAnalysisAssembly"
      
          $Result = 0
          if($InputCoveragePath -and (Test-Path "$InputCoveragePath") )
          {
              [string[]] $coverageFiles = $(Get-ChildItem -Path $InputCoveragePath -Recurse -Include *coverage)
              
              @($coverageFiles) | ForEach-Object {
                  $coverageFile = $_
                  $coverageFileOut = (Join-Path -Path $(Split-Path $_ -Parent) -ChildPath  ($(Get-Item $_).BaseName + "$OutputCoverageFileExtension"))
      
                  Write-Host "If all OK the xml will be written to: $coverageFileOut"
      
                  $info = [Microsoft.VisualStudio.Coverage.Analysis.CoverageInfo]::CreateFromFile($coverageFile, $ExecutablePaths, $SymbolPaths);
                  if($info){
                      $data = $info.BuildDataSet()
                      $data.WriteXml($coverageFileOut)
                  }
              }
          }
          else
          {
              Write-Host "Please specify a valid input coverage file."
              $Result = 1
          }
      
          Write-Host "[CoverageConverter][End]: Coverage conversion completed with result $Result"
          return $Result  
      }
      
      #Run the code in 32bit mode if PowerShell isn't already running in 32bit mode
      If($env:PROCESSOR_ARCHITECTURE -ne "x86"){
          Write-Warning "Non-32bit architecture detected, processing original request in separate 32bit process."
          $Job = Start-Job $RunAs32Bit -RunAs32 -ArgumentList ($InputCoveragePath, $OutputCoverageFileExtension, $CoverageAnalysisAssembly, $ExecutablePaths, $SymbolPaths, $ScriptLocation)
          $Result = $Job | Wait-Job | Receive-Job
      }Else{
          $Result = Invoke-Command -ScriptBlock $RunAs32Bit -ArgumentList ($InputCoveragePath, $OutputCoverageFileExtension, $CoverageAnalysisAssembly, $ExecutablePaths, $SymbolPaths, $ScriptLocation)
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-08-21
        • 1970-01-01
        • 2014-04-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多