Skip to content

Merging Parallel Reports

aryehcitron@gmail.com edited this page Jun 20, 2026 · 4 revisions

Merging Parallel Reports

When a test suite is large, it is often faster to split it across several CI runners that each execute a subset of the tests in parallel. Kronikol can then combine each runner's output into a single combined TestRunReport.html — with the same information as if every test had run together in one process (including one merged Component Diagram across all runners' traffic, internal-flow popups, and flame charts).

This works in two steps:

  1. Each test runner produces an enriched, mergeable TestRunReport.json.
  2. A final job runs kronikol merge over all the JSON files to produce the combined HTML report.

1. Emit mergeable data from each runner

Enable GenerateMergeableData in your report configuration:

new ReportConfigurationOptions
{
    GenerateMergeableData = true,
    // ...your other options
}

Each runner's TestRunReport.json is then enriched with everything needed to rebuild a full report later:

  • Features, scenarios, steps, results, durations and errors
  • Per-scenario sequence/activity diagram source
  • The run's component-diagram relationships
  • Precomputed internal-flow segment data and whole-test-flow fragments
  • CI metadata (commit, branch, run link)

The mergeable file is larger than the standard report because it embeds the precomputed diagram/flame payloads. It is only produced when the data format is JSON (the default).

Upload each runner's TestRunReport.json as a build artifact (see CI Artifact Upload). Give each runner's artifact a distinct name/path so they don't overwrite one another.


2. Combine with kronikol merge

Install the CLI tool (a standard .NET global/local tool):

dotnet tool install --global Kronikol.Tool

Then, in a job that runs after all the test runners have finished and their artifacts have been downloaded into one folder:

kronikol merge ./artifacts -o TestRunReport.html -t "Nightly Build"

Arguments

Argument Description
<inputs...> One or more files, directories (searched recursively for *.json), or glob patterns. Schema files (*.schema.json) are ignored.
-o, --output Output HTML path. Default: TestRunReport.html.
-t, --title Report title. Default: Test Run Report.
-h, --help Show usage.

How merging works

  • Features are grouped by name, so a feature split across runners is recombined; its scenarios are unioned (deduplicated by scenario id).
  • Component relationships are re-aggregated across runners (call counts and test counts sum; method sets are unioned), producing one merged Component Diagram.
  • Internal-flow popups and whole-test-flow fragments are unioned across runners.
  • Times use the earliest start and latest end across all runners.
  • CI metadata is taken from the first runner that captured it (runners in the same workflow share repository, branch and commit).

GitHub Actions example

jobs:
  test:
    strategy:
      matrix:
        shard: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-dotnet@v4
      # Run this shard's subset of the tests (split however you like).
      - run: dotnet test --filter "Shard=${{ matrix.shard }}"
        env:
          # Ensure your ReportConfigurationOptions sets GenerateMergeableData = true.
          KRONIKOL_SHARD: ${{ matrix.shard }}
      - uses: actions/upload-artifact@v4
        with:
          name: report-shard-${{ matrix.shard }}
          path: '**/Reports/TestRunReport.json'

  merge:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/setup-dotnet@v4
      - run: dotnet tool install --global Kronikol.Tool
      - uses: actions/download-artifact@v4
        with:
          path: ./artifacts          # all report-shard-* artifacts land here
      - run: kronikol merge ./artifacts -o TestRunReport.html -t "Combined Test Run"
      - uses: actions/upload-artifact@v4
        with:
          name: combined-report
          path: TestRunReport.html

Programmatic API

If you'd rather merge from your own code instead of the CLI:

using Kronikol.Reports.Merge;

// One-liner: read JSON files, merge, render combined HTML.
MergeableReportRenderer.MergeFilesToHtml(
    new[] { "artifacts/runner1/TestRunReport.json", "artifacts/runner2/TestRunReport.json" },
    "TestRunReport.html",
    title: "Combined Test Run");

// Or step-by-step for full control:
var reports = files.Select(MergeableReportReader.ReadFile).ToList();
var merged = MergeableReportMerger.Merge(reports);
MergeableReportRenderer.Render(merged, "TestRunReport.html");

Limitations

  • Inline step-parameter highlighting and step doc-strings are not yet carried through the mergeable data format. Step text, status, durations, substeps and attachments are preserved.
  • GenerateMergeableData only applies to the JSON data format.

See also

Home


Demo


Getting Started

Common Tasks

Integration Guides

Extensions

Configuration

Features

Reference

Clone this wiki locally