dockerazure-pipelinescode-coverage.net-6.0reportgenerator

ReportGenerator does not show code coverage for individual files


I have a .Net 6 application which has 3 Test Projects. I have Azure DevOps CI/CD pipeline which shows the code coverage report.

In a Dockerfile, I run tests for individual project and generate a code coverage report using ReportGenerator tool. Here is my DockerFile

# Install Report Generator Tool
RUN dotnet tool install dotnet-reportgenerator-globaltool --tool-path /tools

# Run tests for individual test projects to generate test and code coverage report
RUN dotnet test "PreAdviceGeneration.Presentation.UnitTests/PreAdviceGeneration.Presentation.UnitTests.csproj" \
    --logger "trx;LogFileName=PreAdviceGeneration.Presentation.UnitTests.trx" \
    --results-directory /TestResults \
    /p:CoverletOutput=/TestResults/presentation/ /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura 
RUN dotnet test "PreAdviceGeneration.Application.UnitTests/PreAdviceGeneration.Application.UnitTests.csproj" \
    --logger "trx;LogFileName=PreAdviceGeneration.Application.UnitTests.trx" \
    --results-directory /TestResults \
    /p:CoverletOutput=/TestResults/application/ /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura 
RUN dotnet test "PreAdviceGeneration.Infrastructure.IntegrationTests/PreAdviceGeneration.Infrastructure.IntegrationTests.csproj" \
    --results-directory /TestResults \
    --logger "trx;LogFileName=PreAdviceGeneration.Infrastructure.IntegrationTests.trx" \
    /p:CoverletOutput=/TestResults/infrastructure/ /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura

# Convert multiple cobertura reports into one and publish the result to the target directory.
RUN /tools/reportgenerator "-reports:/TestResults/**/coverage.cobertura.xml" \
    "-targetdir:/TestResults/coveragereport" \
    "-reporttypes:Cobertura" \
    "-classfilters:-Models.*;-Constants.*;-Configurtation.*;-Program.cs;-SpmContext.cs" \
    "-verbosity:Verbose"

In the azure pipeline, I first copy test report and the code coverage report stored in the container into the pipeline's host agent. Then run the PublishCodeCoverageResults@1 task. Here is the azure pipeline.

  - task: CmdLine@2
    displayName: Copy test results to the agent
    inputs:
      script: |
        echo 'Default directory is::: $(System.DefaultWorkingDirectory)'
        echo 'Source directory is:::: $(Build.SourcesDirectory)'
        echo 'ArtifactStagingDirectory is:::: $(Build.ArtifactStagingDirectory)'

        docker build -f $(Build.SourcesDirectory)/Dockerfile --target build -t $(Build.BuildId) .
        docker create -ti --name testcontainer $(Build.BuildId)
        docker cp testcontainer:/TestResults ./TestResults
        docker rm -fv testcontainer

  - task: PublishTestResults@2
    displayName: 'Publish test results'
    inputs:
      testResultsFormat: 'VSTest'
      testResultsFiles: '**/*.trx'
      searchFolder: '$(System.DefaultWorkingDirectory)/TestResults'
      failTaskOnFailedTests: true

  - task: PublishCodeCoverageResults@1
    displayName: 'Publish code coverage results'
    inputs:
      codeCoverageTool: Cobertura
      summaryFileLocation: '$(System.DefaultWorkingDirectory)/TestResults/coveragereport/*.xml'

The issue I am facing is that, although it generates the following code coverage report, enter image description here

if I dive into individual file, I see error as File '/src/PreAdviceGeneration.Application/MappingProfiles/DomainItemTopicMessageProfile.cs' does not exist (any more). See the screenshot below enter image description here

PS: Worth mentioning that I cannot install the ReportGenerator plugin in AzureDevops.


Solution

  • The build stage of my docker file had WORKDIR as /app. As tests are run in app directory, the ReportGenerator sets source location starting with /app/..... When the report is copied in Azure Host, and published, it tries to find the source code with the path /app/.... The source code in the Azure host agent lies at the location, $(System.DefaultWorkingDirectory) which is /home/vsts/work/1/s. Hence the published report cannot find the source file.

    Hence to have the consistent path across docker image and Azure Host, I updated the WORKDIR of the build stage of Dockerfile to /home/vsts/work/1/s and now I am able to see the report for individual files.

    My Docker file now looks like:

    FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
    WORKDIR /home/vsts/work/1/s
    COPY . .
    
    .........