Coverage Merging
Many builds generate multiple code coverage reports. Some examples include:
- Builds involving multiple programming languages, where each language requires different coverage instrumentation
- Parallelized builds where each parallel unit (thread, process, virtual machine etc.) may generate its own coverage report
- Different test suites (unit, integration, end-to-end) generating separate reports
Qlty supports merging these separate reports into a single comprehensive report using either Client-Side or Server-Side merging.
- If builds occur on a single machine (or multiple machines with shared storage), client-side merging is often the simplest approach.
- If builds are spread across multiple machines and disks, server-side merging is likely the easiest solution.
Client-side merging
Client-side merging uses the Qlty CLI to combine multiple coverage reports into a single report. That single report is then uploaded to Qlty Cloud for processing.
This is accomplished by passing the locations of your raw coverage reports (as paths or globs) to the qlty coverage publish
subcommand:
Or using glob patterns:
The CLI transforms each of these reports into the Qlty format, then publishes a single coverage report to Qlty Cloud.
Client-side merging is ideal when all of your coverage data files are on a single machine.
Server-side merging
With server-side merging, a build publishes a series of partial reports to Qlty; when Qlty Cloud knows it’s received all parts (as determined by the below options), it aggregates and reports coverage for that commit SHA.
Server-side merging is ideal when:
- Your tests run on multiple machines without shared storage
- You want to avoid collecting all reports in a single location
- Each report file may require unique path fixing
Qlty provides two strategies for server-side merging:
total-parts-count
This approach works by specifying a --total-parts-count=NUM
argument to the qlty coverage publish
subcommand when publishing a coverage part. If, for example, your build consists of 2 parallelized builds, Qlty Cloud will wait for 2 coverage publish commands:
Use total-parts-count
when you can easily know exactly how many coverage uploads will be made.
coverage complete
This approach is useful when you don’t know the total number of parts in advance, or in complex CI environments where determining the total number ahead of time is impractical.
- Upload all parts with the
--incomplete
flag:
- After all parts have been uploaded, send a “Complete” signal to tell Qlty that all parts have been received:
When Qlty receives the completion signal, it will finalize the coverage report, merging all the received parts.
Use the coverage complete
command when:
- The number of parts isn’t easily known everywhere in advance
- Your CI workflow has dynamic job generation
- You have a complex build pipeline where tracking total parts is difficult
Client and server-side merging together
Client-side and server-side merging can also be used together: each machine itself can combine multiple coverage reports using client-side merging, and then post that combined report to Qlty as part of server-side merging.
The total parts count always equals the number of total publish commands executed, regardless of the number of paths passed to the subcommand. If 2 machines perform client-side aggregation of N paths, qlty coverage publish
should specify “2” as the total parts count.
Merging with coverage tags
The qlty coverage publish
command, whether used for client or server-side merging, is always for a single tag (no no tag).
Client-side merging with tags
With client-side merging, you need to publish N reports if there are N tags (If there are 3 coverage tags, the build should execute qlty coverage publish
3 times):
Server-side merging with tags
total-parts-count
with tags
When using the total-parts-count approach with tags, you need to specify the total number of parts for each tag separately. This means that if you have multiple tags, you should publish each tag’s parts separately.
With the total-parts-count approach, the --total-parts-count
should reflect the number of total parts Qlty Cloud should expect for that tag.
For example, if there’s 4 reports with an “integration” tag and 2 reports with a “unit” tag, your build should publish 4 integration reports and 2 unit reports as follows:
coverage complete
with tags
When using the --incomplete
flag approach with tags, you must complete each tag separately. For each tag, upload all parts with the --incomplete
flag, then send a completion signal for that specific tag:
Common Scenarios
Build matrix
In GitHub Actions or other CI systems that support matrix builds:
Multiple languages
For a project with both JavaScript and Python code:
Verifying merging
After publishing your coverage reports, you can verify that merging was successful:
- Navigate to your project in Qlty Cloud
- Go to Project Settings → Code Coverage
- Filter the table below “Code Coverage Setup” by commit
- You should see N + 1 reports:
- N individual parts representing the reports you sent
- 1 final merged report representing the combined coverage
Troubleshooting
Missing parts
If your merged report doesn’t appear after several minutes:
For Total Parts Count approach:
- Check that all parts were successfully uploaded
- Verify that the
--total-parts-count
value matches the actual number of uploads - Ensure all parts were uploaded for the same commit SHA and branch
- Check that all parts used the same tag (if using tags)
Completion Signal Issues
If you’re using the incomplete flag approach and experiencing issues:
- Ensure that all parts were uploaded with the
--incomplete
flag (otherwise,qlty coverage publish
assumes by default that the report is complete) - Verify the completion command was executed for each tag you’re tracking
- Check that both upload and completion commands are using the same credentials and workspace
- Verify all coverage parts were uploaded with the same commit SHA and branch
Partial merging
If some files are missing from your merged coverage:
- Verify that all coverage reports were valid and complete
- Check for path differences between reports
- Ensure all reports use compatible formats
- Consider using path fixing options if paths don’t match
See Also
- Coverage Tags - Track different types of tests separately
- CI Integration - Automate coverage reporting in your CI pipeline
- Path Fixing - Fix path discrepancies in coverage reports