Handling Multiple Coverage Reports with Jest Shards

Hi Community Managers,

I noticed that the JavaScript / TypeScript test coverage | SonarQube Server | Sonar Documentation doesn’t address how to handle multiple coverage reports. This is a common scenario when using jest shards, especially in CI environments like GitHub Actions.

Currently, it’s unclear whether the SonarQube scanner automatically merges multiple reports, or if users are expected to merge them manually and configure the analysis to use the consolidated report.

My scenario:

  • Platform: GitHub
  • CI: GitHub Actions
  • SonarQube Action: SonarSource/sonarqube-scan-action@v7
  • Languages: TypeScript/JavaScript
  • Setup: Tests run on multiple shards, each generating a separate lcov.info coverage report

Observed behavior:

  • Incorrect coverage in SonarQube when:
    • Jest coverageProvider is set to v8
    • Individual reports are provided via:
      sonar.javascript.lcov.reportPaths=coverage-artifacts/**/lcov.info
      
  • Correct coverage in SonarQube when:
    • Jest coverageProvider is set to babel
    • Reports are merged using:
      lcov $(find coverage-artifacts -name 'lcov.info' | xargs -I{} echo -a {}) -o coverage-artifacts/merged-lcov.info
      
    • The merged report is provided via:
      sonar.javascript.lcov.reportPaths=coverage-artifacts/merged-lcov.info
      

For reference, I found Sonar scanner has no coverage data with 2 jest shards - #21 by koestnei on a similar topic, but it doesn’t clarify the recommended approach.

Request:

Could you please add a dedicated section in the documentation about the expected workflow for handling multiple coverage reports?

Thank you!

Hi,

Per the docs:

Some properties support the following wildcards in paths. The remarks for properties that support wildcards will mention this fact.

The remarks for sonar.javascript.lcov.reportPaths do not mention supporting wildcards. Sorry, but you’ll have to type out the comma-delimited list the parameter is expecting.

 
HTH,
Ann

Hi @ganncamp,

Thank you so much for your response! I really appreciate your help.

I wanted to clarify a couple of points and suggest a possible update to the documentation:

  1. It appears that wildcards are actually supported, even though this isn’t currently mentioned in the documentation. For example, when using sonar.javascript.lcov.reportPaths=coverage-artifacts/**/lcov.info, the analyzer detects the files as showed by the logs below:

    INFO Analysing [/home/runner/work/.../coverage-artifacts/lcov-info-shard-1/lcov.info, /home/runner/work/.../coverage-artifacts/lcov-info-shard-2/lcov.info, /home/runner/work/.../coverage-artifacts/lcov-info-shard-3/lcov.info]
    
  2. My main concern is about how these separate coverage files are processed by the analyzer. The documentation doesn’t seem to specify this. In my experience, Sonar was unable to reconcile the coverage correctly when analyzing multiple files. However, after explicitly merging the files, the coverage was reported correctly:

    INFO Analysing [/home/runner/work/.../coverage-artifacts/merged-lcov.info]
    

Would it be possible to check with the development team and consider updating the documentation? It would be really helpful to add a section about handling coverage for Jest shards and clarify how multiple coverage files are processed.

Thanks again for your support!
:slight_smile:

1 Like

Hi,

Okay, fair points. I’ve flagged this for the team.

 
Ann

2 Likes

Hello @abuono_pictet,

I created a ticket to improve our lcov importing when merging reports.

Thanks for reporting this!

Victor

2 Likes

You’re welcome! :blush:

It’s always nice to help out and make things better.

@ganncamp, maybe one of these days I’ll earn a community hero t-shirt also as a user! :face_with_tongue:

2 Likes

Hi @abuono_pictet,

the fix was merged and SonarJS was released today. Should be deployed in a couple of days. Please let me know if the lcov import is working as expected with SonarJS 12.1

Cheers!

2 Likes