Karate's Built-in HTML Reports

7 min read

Every Karate test run generates a detailed HTML report automatically. No extra Maven plugin, no reporting library, no configuration — the report is always there when the run finishes. This lesson covers what the report contains, where to find it, how to read it for debugging, and what to enable when you need a richer output for CI dashboards.

Where the report lives

After mvn test, Karate writes two types of output to target/karate-reports/:

  • karate-summary.html — the top-level dashboard: total features, scenarios run, pass/fail counts, elapsed time, and links to per-feature detail pages.
  • One *.html file per feature file — each contains every scenario from that feature, step by step.
  • One *.json file per feature file — Cucumber-compatible JSON that third-party tools consume.

Open karate-summary.html in any browser. No web server needed — it's a self-contained static file with all assets bundled inline.

What each section shows

The scenario detail page — where debugging happens

The most valuable page is the per-scenario view. Expand a failed scenario and you see:

  • The exact URL that was called (including query parameters)
  • Every request header sent
  • The full request body
  • The HTTP status code and response headers
  • The full response body, pretty-printed
  • The exact assertion that failed, with the actual value on the left and the expected value on the right

When a test fails in CI and you need to know why, the scenario detail page answers the question without needing to reproduce the failure locally. This is the feature that makes Karate reports genuinely useful for a distributed team — the evidence is in the report, not just in someone's terminal.

Report generation for parallel runs

The Runner.path(...).parallel(N) runner merges results from all threads into a single unified report. The summary page covers all features from all threads. Individual feature pages are generated per feature file, not per thread. The final report is indistinguishable from a sequential run report — the parallelism is an implementation detail, invisible to the reader.

Results results = Runner
    .path("classpath:users", "classpath:orders")
    .outputCucumberJson(true)
    .parallel(4);

.outputCucumberJson(true) enables the Cucumber-compatible JSON output alongside the built-in HTML. Enable it whenever you plan to use a third-party reporting tool — it costs nothing and can't be generated retroactively after the run.

Screenshots from UI tests

When Karate UI tests run, any screenshot() step saves an image to target/karate-reports/. The image is linked directly from the scenario detail page — click the screenshot thumbnail to see the browser state at the moment it was captured. This works without any additional configuration.

Failed UI steps also automatically save a screenshot of the browser state at the point of failure. You don't need to add screenshot() calls around every assertion — Karate does it on failure automatically.

Inspecting timing data

Every scenario shows its elapsed time. Every method call shows the response time in milliseconds. You can scan a feature's scenario list and immediately spot the outliers — a scenario that takes 8 seconds in a 1-second suite is worth investigating even when it passes.

The summary page shows total elapsed time for the whole run, which is the number you compare before and after parallel execution changes.

⚠️ Common mistakes

  • Not opening the HTML report when a CI build fails. The console output shows the assertion error message but not the response body. The HTML report shows both. Teams that debug only from the console waste time reproducing failures locally that the report would explain in 30 seconds. Make it a habit: CI fails → open the artifact → read the scenario page.
  • Forgetting outputCucumberJson(true) before you need third-party reports. The Cucumber JSON can't be regenerated after a run. If you decide mid-project to add Cucumber Reports or Allure integration, you need to re-run the suite with the flag enabled. Add it in the parallel runner from the beginning — it adds negligible overhead.
  • Treating the summary pass percentage as the only signal. A suite where 95% of scenarios pass can still have a critical regression in the 5% that failed. Always look at which specific scenarios failed, not just the headline number. The report's feature list makes it easy to drill into the failures quickly.

🎯 Practice task

Read the HTML report at three levels of detail. 20–30 minutes.

  1. Run mvn test on your Karate project. Open target/karate-reports/karate-summary.html in a browser. Note the total scenario count, pass percentage, and total elapsed time.
  2. Click through to a feature page. Expand a passing scenario and read every step — note the response time shown after the method step.
  3. Force a failure: change a match assertion to an incorrect expected value. Run again. Open the report, find the failed scenario, expand it. Locate the HTTP request body, the response body, and the assertion failure detail. Confirm the report shows the actual value the API returned.
  4. Add .outputCucumberJson(true) to your runner. Run the suite. Open target/karate-reports/. Find the .json file alongside the .html files. Open it in a text editor — it's the same data in machine-readable format.
  5. If you have any Karate UI tests from the previous chapter, run them and find the screenshot links in the scenario page. If not, add a screenshot() step to a UI scenario and confirm the image appears in the report.
  6. Stretch: open the Cucumber JSON file and identify the structure — features, elements (scenarios), steps, result (status, duration). This is the format third-party report tools parse. The next lesson shows you how to feed this into the Cucumber Reports plugin.

Next lesson: integrating with Cucumber Reports and Allure — richer dashboards, trend data, and CI-friendly reporting.

// tip to track lessons you complete and pick up where you left off across devices.