Pradeep
Pradeep

Reputation: 5540

How to exclude test code from code coverage results using Azure DevOps build pipeline

I am compiling an .Netcore application using Azure DevOps build pipeline. In the .Netcore test build task, I have passed the below arguments for collecting the code coverage results:

--configuration $(BuildConfiguration) --collect"XPlat Code Coverage"

For publishing Code Coverage results, I have used "Publish Code Coverage Results" build task using "Cobertura" tool.

The code coverage analyzes all solution assemblies that are loaded during unit tests. But I want to exclude test code from code coverage results and only include application code through the Azure DevOps build pipeline.

For that I have referred this documentation. Based on this documentation you need to add the “ExcludeFromCodeCoverageAttribute” attribute to each test class. But I want do it through the Azure DevOps build pipeline.

Upvotes: 3

Views: 3348

Answers (2)

Mihai Socaciu
Mihai Socaciu

Reputation: 715

I managed to exclude unit tests in Cobertura format in Azure DevOps pipeline with the following. Note the usage of:

  • XPlat Code Coverage instead of Code Coverage.
  • --settings $(unittestsRunSettings) in test command
  • reports: '$(Agent.TempDirectory)/**/*.cobertura.xml' identifying all raw test files

CodeCoverage.runsettings

<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
  <DataCollectionRunSettings>
    <DataCollectors>
      <DataCollector friendlyName="XPlat Code Coverage" uri="datacollector://Microsoft/CodeCoverage/2.0" assemblyQualifiedName="Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector, Microsoft.VisualStudio.TraceCollector, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
        <Configuration>
          <Format>Cobertura</Format>
          <CodeCoverage>
            <ModulePaths>
              <Exclude>
                <ModulePath>.*MyApp.Repositories.dll$</ModulePath>
              </Exclude>
            </ModulePaths>

            <Functions>
              <Exclude>
                <Function>.*Program\..*</Function>
                <Function>.*Startup\..*</Function>
                <Function>.*Settings\..*</Function>
                <Function>.*Setting\..*</Function>
                <Function>.*Exception\..*</Function>
              </Exclude>
            </Functions>
          </CodeCoverage>
        </Configuration>
      </DataCollector>
    </DataCollectors>
  </DataCollectionRunSettings>
</RunSettings>

pipeline.yml

variables:
  unittestsRunSettings: '$(Build.Repository.LocalPath)\src\CodeCoverage.runsettings'


# Run unit tests with cobertura coverage format
- task: DotNetCoreCLI@2
  displayName: 'Run Unit Tests - $(buildConfiguration)'
  inputs:
    command: 'test'
    arguments: '--no-build --configuration $(buildConfiguration) --collect "XPlat Code Coverage" --settings $(unittestsRunSettings)'
    publishTestResults: true
    projects: '**/*Test*.csproj'

# Publish code coverage report to the pipeline
- task: reportgenerator@5
  displayName: 'Merge code coverage reports'
  inputs:
    reports: '$(Agent.TempDirectory)/**/*.cobertura.xml'
    targetdir: '$(Pipeline.Workspace)/coverlet'
    reporttypes: 'Cobertura'
    verbosity: 'Verbose'
     
- task: PublishCodeCoverageResults@1
  displayName: 'Publish code coverage results'
  inputs:
    codeCoverageTool: Cobertura
    summaryFileLocation: '$(Pipeline.Workspace)/coverlet/Cobertura.xml'

Upvotes: 0

Gioce90
Gioce90

Reputation: 623

I was in your same situation months ago. But instead of Coverlet I'm using the native MS Code Coverage tool in this way:

  - task: DotNetCoreCLI@2
    displayName: 'DotNetCoreCLI Test with report (cobertura format)'
    condition: succeededOrFailed()
    inputs:
      command: test
      projects: '**/**.Tests.csproj'
      arguments: '--configuration $(BuildConfiguration) --no-restore --collect "Code Coverage" --logger trx --results-directory "TestResults/Coverage/" -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura'
      publishTestResults: false

This works well but there is your same problem. I resolved using filtering with ReportGenerator task:

  - task: reportgenerator@5
    condition: succeededOrFailed()
    inputs:
      reports: '$(Build.SourcesDirectory)/TestResults/Coverage/**/**.cobertura.xml'
      targetdir: '$(Build.SourcesDirectory)/TestResults/Coverage/Reports'
      reporttypes: 'HtmlInline_AzurePipelines_Dark;Cobertura'
      assemblyfilters: '+My.Company.**;-My.Company.**.Tests'

It works well. For other questions, see my GitHub answer here

Upvotes: 1

Related Questions