Search code examples
azure-devopsazure-pipelinescode-coveragexunitsonarcloud

SonarCloud Code coverage report for .Net not working on Linux agent in Azure DevOps


For our build pipeline in Azure DevOps we have switched to using the ubuntu-latest vm-image and since that switch I have noticed we no longer receive code coverage information.

I have verified that the problem is due to using a Linux agent by switching back to windows and see that it worked, however due to a problem with the current Windows agents we have to use the Linux agent.

Is it possible there is a problem with the default path that sonar checks for the coverage information?

Below the pipeline:

pool:
  vmImage: 'ubuntu-latest'

variables:
  solution: 'src/PDO.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'

steps:

- checkout: self
  fetchDepth: 0

- task: FileTransform@1
  inputs:
    folderPath: '$(System.DefaultWorkingDirectory)'
    fileType: 'json'
    targetFiles: '/**/appsettings.*.json'

- task: SonarCloudPrepare@1
  displayName: 'Prepare analysis on SonarCloud'
  inputs:
    SonarCloud: 'SonarCloud'
    organization: '***'
    scannerMode: 'CLI'
    configMode: 'manual'
    cliProjectKey: '***'
    cliProjectName: '***'
    cliSources: '.'
    
- task: DockerCompose@0
  displayName: Start dependencies (docker-compose)
  inputs:
    containerregistrytype: Container Registry
    dockerComposeFile: docker-compose.yml
    dockerComposeCommand: 'up -d'

- task: UseDotNet@2
  inputs:
    version: '7.x'

- task: NuGetToolInstaller@1
  displayName: Install Nuget  

- task: NuGetCommand@2
  displayName: Restore Nuget packages PDO.sln
  inputs:
    restoreSolution: '$(solution)'
    
- task: DotNetCoreCLI@2
  displayName: Build Solution
  inputs:
    command: 'build'
    arguments: '--configuration $(buildConfiguration)'
    projects: '$(solution)'  
    
- task: DotNetCoreCLI@2
  displayName: Run Unit Tests
  inputs:
    command: 'test'
    arguments: '--no-build --configuration $(BuildConfiguration)  --collect "Code Coverage"'
    projects: 'src/PDO.Unit.Tests/PDO.Unit.Tests.csproj'
    testRunTitle: 'Net Core Tests'  

- task: DotNetCoreCLI@2
  displayName: Run Integration Tests
  inputs:
    command: 'test'
    arguments: '--no-build --configuration $(BuildConfiguration) --collect:"Code Coverage" '
    projects: 'src/PDO.Integration.Tests/PDO.Integration.Tests.csproj'
    testRunTitle: 'Net Core Tests'
  env:
    TestSettings:ConnectionStringFormat: $(TestSettings:ConnectionStringFormat) 

- task: SonarCloudAnalyze@1
  displayName: 'Run Code Analysis'
  inputs:
    jdkversion: 'JAVA_HOME_17_X64'
    
- task: SonarCloudPublish@1
  displayName: 'Publish Quality Gate Result'
  inputs:
    pollingTimeoutSec: '300'

Solution

  • I have got it working by now using OpenCover.

    In the sonar prepare step I have added the following:

    extraProperties: |
           sonar.cs.opencover.reportsPaths=$(Agent.TempDirectory)/*/coverage.opencover.xml
    

    Then the test step I have defined as follows:

    - task: DotNetCoreCLI@2
        displayName: 'Unit tests'
        inputs:
          command: 'test'
          projects: '**/*.UnitTests.csproj'
          arguments: '--no-build --configuration $(buildConfiguration) --collect:"XPlat Code Coverage" -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura,opencover'
    

    Note the two formats, Cobertura is used to create a code coverage report in DevOps, and Opencover to create a report for SonarCloud

    To get the Cobertura report in DevOps I added an additional step to publish the report, this is not needed for Sonar:

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