Опубликовать отчет о покрытии кода конвейера Azure Devops

#azure-devops #azure-pipelines #code-coverage #pipeline #cobertura

#azure-devops #azure-конвейеры #покрытие кода #конвейер #cobertura

Вопрос:

Я пытаюсь опубликовать подробный отчет онлайн в моем конвейере Azure DevOps, но все, что я получил, это ссылку для загрузки этого файла покрытия. (Который больше нельзя прочитать в версии сообщества, начиная с Visual Studio 2019) введите описание изображения здесь

Это мой конвейер:

 trigger:
  branches:
    include:
    - '*'

pool:
  vmImage: 'windows-2019'

steps:
- task: NuGetToolInstaller@0
  displayName: Instal Nuget
  inputs:
    checkLatest: true

- task: NuGetCommand@2
  displayName: Restore Nuget Packages
  inputs:
    restoreSolution: '**/*.sln'

- task: UseDotNet@2
  displayName: 'Install .NET Core SDK'
  inputs:
    version: 3.1.x
    performMultiLevelLookup: true

- task: DotNetCoreCLI@2
  displayName: Build Tests
  inputs:
    command: 'build'
    projects: '**/OneTienditaUnitTests/*.csproj'
    arguments: '--configuration Release'

- script: dotnet test OneTienditaUnitTests --logger trx --collect "Code coverage"

- task: PublishTestResults@2
  inputs:
    testRunner: VSTest
    testResultsFiles: '**/*.trx'

- task: XamarinAndroid@1
  displayName: Build Android App
  inputs:
    projectFile: '**/*Android*.csproj'
    outputDirectory: '$(build.binariesDirectory)/Release'
    configuration: 'Release'
  

и если я использую Cobertura таким образом, это не работает:

 - task: DotNetCoreCLI@2
  displayName: Run Tests
  inputs:
    command: 'test'
    projects: '**/OneTienditaUnitTests/*.csproj'
    arguments: '--configuration Release /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput=../reports/coverage/'
    
- task: PublishCodeCoverageResults@1
  displayName: 'Publish code coverage results'
  inputs:
    codeCoverageTool: Cobertura
    summaryFileLocation: '$(build.sourcesdirectory)reportscoveragecoverage.cobertura.xml'
    reportDirectory: '$(build.sourcesdirectory)reportscoverage'
  

Пожалуйста, любая помощь? Я не профессиональный DevOps

Ответ №1:

Чтобы опубликовать отчет, вам необходимо использовать Cobertura. Для TRX вы получите только ссылку для загрузки файла. А для создания отчета Cobertura вам необходимо установить в свои тестовые проекты coverlet.collector пакет nuget. Здесь у вас есть код, который должен решить вашу проблему:

 # You just added coverlet.collector to use 'XPlat Code Coverage'
- task: DotNetCoreCLI@2
  displayName: Test
  inputs:
    command: test
    projects: '**/*Tests/*.csproj'
    arguments: '--configuration $(buildConfiguration) --collect:"XPlat Code Coverage" -- RunConfiguration.DisableAppDomain=true'
    workingDirectory: $(Build.SourcesDirectory)

- task: DotNetCoreCLI@2
  inputs:
    command: custom
    custom: tool
    arguments: install --tool-path . dotnet-reportgenerator-globaltool
  displayName: Install ReportGenerator tool

- script: ./reportgenerator -reports:$(Agent.TempDirectory)/**/coverage.cobertura.xml -targetdir:$(Build.SourcesDirectory)/coverlet/reports -reporttypes:"Cobertura"
  displayName: Create reports

- task: PublishCodeCoverageResults@1
  displayName: 'Publish code coverage'
  inputs:
    codeCoverageTool: Cobertura
    summaryFileLocation: $(Build.SourcesDirectory)/coverlet/reports/Cobertura.xml  
  

[ОБНОВЛЕНИЕ 2021 ГОДА]

Вам не нужны дополнительные задачи для установки / запуска пользовательского инструмента ReportGenerator: теперь это инструмент по умолчанию для чтения coverage.cobertura.xml файлов и включен в dotnet CLI.

Однако по умолчанию XML-файл cobertura будет сохранен во временном каталоге агента. Итак, вам просто нужно обновить summaryFileLocation PublishCodeCoverageResults задачу, чтобы указать на временный каталог и пропустить шаги «посредника»:

 # You just added coverlet.collector to use 'XPlat Code Coverage'
- task: DotNetCoreCLI@2
  displayName: Test
  inputs:
    command: test
    projects: '**/*Tests/*.csproj'
    arguments: '--configuration $(buildConfiguration) --collect:"XPlat Code Coverage"'

- task: PublishCodeCoverageResults@1
  displayName: 'Publish code coverage'
  inputs:
    codeCoverageTool: Cobertura
    summaryFileLocation: '$(Agent.TempDirectory)/**/coverage.cobertura.xml'
  

Если у вас есть несколько тестовых проектов, которые генерируют несколько файлов покрытия, пожалуйста, выполните следующие действия после тестовой запятой. Он объединит файлы перед их публикацией:

   - task: reportgenerator@4
    displayName: "Merge code coverage reports"
    inputs:
      reports: "**/coverage.cobertura.xml"
      targetdir: "$(Build.ArtifactStagingDirectory)/coverlet"
      reporttypes: "Cobertura"
      verbosity: "Verbose"

  - task: PublishCodeCoverageResults@1
    displayName: "Publish code coverage results"
    inputs:
      codeCoverageTool: Cobertura
      summaryFileLocation: "$(Build.ArtifactStagingDirectory)/coverlet/Cobertura.xml"
  

Комментарии:

1. это работает, но небольшая деталь, в строке «script» мне пришлось убрать «. /» в начале. Спасибо, полностью отсутствовала часть установки.

2. Спасибо. Есть ли идея, если в документах MS предлагается объединить все эти шаги в один, учитывая покрытие кода XPlat? learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test

3. Что ж, вы можете создать шаблон, содержащий эти шаги, и повторно использовать его в своих конвейерах.

4. С лета 2021 года вам не нужны дополнительные задачи для установки / запуска ReportGenerator, поскольку теперь он является инструментом по умолчанию для чтения coverage.covertura.xml файлов. Вам просто нужно обновить summaryFileLocation PublicCodeCoverageResults задачу, чтобы указать на временный каталог, как вы уже делаете с задачей сценария, проходящей по пути к ReportGenerator

5.Я пробовал эти шаги, и, к сожалению, задача публикации завершается с ошибкой: Multiple file or directory matches were found. Using the first match: C:agent_work38sartifactstest-results$redactedInredactedcoverage.cobertura.xml ##[error]No code coverage results were found to publish. Я понятия не имею, что происходит. Когда я запускаю dotnet test локально, я вижу, что все coverage.cobertura.xml файлы генерируются, как и ожидалось. Я даже вижу их в dotnet test выходных данных моего конвейера.

Ответ №2:

Я много пытался решить его проблему…

Итак, прежде всего, проблема заключается в тестовой задаче конвейера (в моем случае задача DotNetCoreCLI @ 2). Если эта задача собирает покрытие кода, она автоматически публикуется вместе с тестами в формате .coverage. По какой-то причине это нажатие файла .coverage находится в конце конвейера (или задания — этого я не знаю) и, следовательно, переопределяет все ранее загруженные файлы.

Решение использует инструмент покрытия, такой как OpenCover, и собирает покрытие кода с его помощью вместо коллекции с помощью тестового задания с включенной коллекцией CodeCoverage.

Пример:

OpenCover.Console.exe -target:"dotnet.exe" -targetArgs:"test {solution.sln}" -output:"{outputDir}OpenCover.xml" {-oldstyle}

Затем преобразуйте файл OpenCover с помощью задачи ReportGenerator в формат Cobertura.

И после этого вы можете опубликовать его как обычно с помощью задачи PublishCodeCoverageResult.

Возможно, вам придется немного попробовать, но с учетом этого решения оно будет работать.

Ответ №3:

У меня была такая же проблема с отрисовкой отчетов Azure DevOps и code coverage. Я перепробовал все под солнцем, но безрезультатно. Были решения с повышением голосов, но, похоже, ни одно из них не работает для меня. Я всегда получал только эту глупую ссылку для скачивания.

После прочтения ответа @h0p3zZ он дал мне новую подсказку. По какой-то причине моя dotnet test команда генерировала оба coverage.cobertura.xml *.coverage файла amp;, и по какой-то странной причине этот файл получает приоритет над coverage.cobertura.xml файлы (что заставляет devops отображать ссылку для скачивания).

В моем случае я передавал .runsettings файл dontnet test команде, как показано ниже, и это заставило ее выдать дополнительный .coverage файл.

 - task: DotNetCoreCLI@2
  displayName: Test
  inputs:
    command: test
    projects: '**/*Tests/*.csproj'
    arguments: --configuration $(buildConfiguration) --collect:"XPlat Code Coverage"  --settings CodeCoverage.runsettings
  

Как только я избавился от --settings CodeCoverage.runsettings switch, все начало работать просто отлично.