skip to Main Content

I run a coverage test in for a python package in AzureDevops but surprisingly the result displayed in the interface is not corresponding to the one I have in the index.html artifact.

Here is the relevant part of the pipeline:

  - stage: coverage
    pool:
      vmImage: ubuntu-latest
    jobs:
      - job: coverage
        steps:
          - task: UsePythonVersion@0
            inputs:
              versionSpec: "3.9"
            displayName: Use Python 3.9
          - script: python -m pip install nox
            displayName: Install dependencies
          - script: nox -s test
            displayName: Test with pytest and coverage
          - task: PublishCodeCoverageResults@2
            displayName: Publish code coverage results
            inputs:
              summaryFileLocation: "coverage.xml" 

When I open the coverage tab in the pipeline results I see this:

enter image description here

And when I open the artifact content I get this:

enter image description here

I guess the second one should be displayed (thats the one I see on other people screenshot) can someone explain me what I am missing and why I got a degraded version of my report ?

EDIT

I tried several configuration changes, I see the expected display from time to time but always fail to see it consistently.
This is the output of the coverage step which seems to publish all the html files as it should:

Found 1 result(s) matching pattern: /home/vsts/work/1/s/coveragereport/Cobertura.xml
/home/vsts/work/1/s/coveragereport/Cobertura.xml
/home/vsts/work/_tasks/PublishCodeCoverageResults_2a7ebc54-c13e-490e-81a5-d7561ab7cd97/2.229.0/node_modules/coveragepublisher/CoveragePublisher/linux-x64/CoveragePublisher.Console /home/vsts/work/1/s/coveragereport/Cobertura.xml --reportDirectory /home/vsts/work/_temp/8c31089b-eb58-422e-9384-3424e6509cea
2023-12-05T10:39:38: Loading report '/home/vsts/work/1/s/coveragereport/Cobertura.xml' 1/1 in memory
2023-12-05T10:39:38: Preprocessing report
2023-12-05T10:39:38: Initiating parser for Cobertura
2023-12-05T10:39:38: Current Assembly: .
2023-12-05T10:39:38: Current Assembly: assets
2023-12-05T10:39:38: Current Assembly: task_monitor
2023-12-05T10:39:38: Finished parsing '/home/vsts/work/1/s/coveragereport/Cobertura.xml' 1/1
2023-12-05T10:39:38: Parsing of 1 files completed
2023-12-05T10:39:38: Starting merging result 1
2023-12-05T10:39:38: Finished merging result 1
2023-12-05T10:39:38: Initializing report builders for report types: HtmlInline_AzurePipelines
2023-12-05T10:39:38: Analyzing 27 classes
2023-12-05T10:39:38: Creating report 1/27 (Assembly: ., Class: __init__.py)
2023-12-05T10:39:38: Writing report file '._py.html'
2023-12-05T10:39:38: Creating report 2/27 (Assembly: ., Class: _deprecated_boundaries.py)
2023-12-05T10:39:38: Writing report file '._py.2.html'
2023-12-05T10:39:38: Creating report 3/27 (Assembly: ., Class: _deprecated_ee_string.py)
2023-12-05T10:39:38: Writing report file '._py.3.html'
2023-12-05T10:39:38: Creating report 4/27 (Assembly: ., Class: _deprecated_image.py)
2023-12-05T10:39:38: Writing report file '._py.4.html'
2023-12-05T10:39:38: Creating report 5/27 (Assembly: ., Class: _deprecated_imagecollection.py)
2023-12-05T10:39:38: Writing report file '._py.5.html'
2023-12-05T10:39:38: Creating report 6/27 (Assembly: ., Class: _deprecated_table.py)
2023-12-05T10:39:38: Writing report file '._py.6.html'
2023-12-05T10:39:38: Creating report 7/27 (Assembly: ., Class: accessor.py)
2023-12-05T10:39:38: Writing report file '._py.7.html'
2023-12-05T10:39:38: Creating report 8/27 (Assembly: ., Class: auth.py)
2023-12-05T10:39:38: Writing report file '._py.8.html'
2023-12-05T10:39:38: Creating report 9/27 (Assembly: ., Class: batch.py)
2023-12-05T10:39:38: Writing report file '._py.9.html'
2023-12-05T10:39:38: Creating report 10/27 (Assembly: ., Class: data.py)

2

Answers


  1. Chosen as BEST ANSWER

    It seems the expected behavior is more complicated to get or the documentation is missing critical parts to make it right.

    On the other hand, the ReportGenerator maintainer has been very nice at answering the [same question][https://github.com/danielpalme/ReportGenerator/issues/637) so I'm publishing the method they use here. As a reminder, ReportGenerator is the OS tool used by PublishCodeCoverage@2to generate html output, the difference being that here it works.

    The trick is to fall back to v1 of PublishCodeCoverage and prevent the tool from regenerating the Cobertura file:

    - task: reportgenerator@5
      displayName: ReportGenerator
      inputs:
        reports: "coverage.xml"
        targetdir: "coveragereport"
        reporttypes: "HtmlInline_AzurePipelines;Cobertura"
    - task: PublishCodeCoverageResults@1
      displayName: Publish code coverage results
      inputs:
        summaryFileLocation: $(Build.SourcesDirectory)/coveragereport/Cobertura.xml
        reportDirectory: $(Build.SourcesDirectory)/coveragereport
        codecoverageTool: cobertura
        env:
          DISABLE_COVERAGE_AUTOGENERATE: "true"
    

  2. The coverage report comes from the file coverage.xml not index.html. You can find it in your task below:

     - task: PublishCodeCoverageResults@2
        displayName: Publish code coverage results
        inputs:
          summaryFileLocation: "coverage.xml" 
    
    • coverage.xml and index.html have different Reporting Goals:
      The coverage.xml file is typically used to integrate with tools that require a specific XML format for code coverage data, such as continuous integration services or code quality analysis tools. On the other hand, index.html is generated to provide a human-readable, detailed coverage report that can be viewed in a web browser.

    • The coverage tool can be configured to include or exclude certain files or directories, which might affect the reports differently. In addition, the way coverage is calculated can vary based on the configuration and the specific commands used to generate the reports.

    Hence, there could be some difference between coverage.xml and index.html

    You can export the coverage.xml to compare the content with index.html for a check.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search