Testland
Browse all skills & agents

test-run-summary-author

Build-an-X workflow that turns a structured test-run artifact (JUnit XML, Allure JSON, TestRail / Xray / Zephyr export) plus optional release context (version, build URL, deploy target) into a narrative markdown summary for release notes, an exec status update, or a stand-up Slack post. Distinct from the per-framework parsers junit-xml-analysis / allure-reports / coverage-diff-reporter, which emit structured tabular reports: this skill takes the same data and writes the human-readable narrative. Use when a manager needs a draft release note or stand-up summary from a single run; for cross-run trend analytics use currents-integration.

Install with skills.sh (any agent)

npx skills add testland/qa --skill test-run-summary-author
View source

test-run-summary-author

Overview

A test run produces structured data (pass / fail counts, duration, failures with stack traces, coverage). A status update needs narrative (one-paragraph summary, top-3 highlights, single-line status banner). Closing the gap is what 70% of practitioners already do with chat models per PractiTest's 2026 State of Testing Report (opens in new window), but with two known failure modes: hallucinated numbers and inconsistent tone across runs. This skill constrains the output shape so the same input always produces the same structure, removing the variance.

The skill is the manager-layer equivalent of the structured-parser skills. Where junit-xml-analysis produces a parsed report, this skill produces the prose draft a manager edits before pasting into Slack / a release-notes PR / an exec-summary email.

When to use

  • A release is going out and the team needs draft release notes from the release-build's test results.
  • A daily / weekly stand-up needs a one-paragraph "where are we" status from a recent CI run.
  • A retro / QBR needs a per-release narrative summary across multiple runs over a time window.
  • An exec asks "what's the QA state for v3.4.0?" and the manager needs a defensible, traceable answer drafted from real data.

Do not use this skill to:

  • Produce a full tabular report - that is the job of junit-xml-analysis, allure-reports, or coverage-diff-reporter.
  • Surface flake patterns over time - that is longitudinal suite-health trend reporting, not this skill.
  • Roll up multiple suites across multiple environments in one report - that is a separate cross-suite roll-up, not this skill's single-run scope.

How to use

  1. Ingest one structured run artifact - JUnit XML, an Allure results directory, or a test-management API export (Ingest the run data).
  2. Compute the six load-bearing numbers from the input; never invent a metric the input lacks (Compute the load-bearing numbers).
  3. Pick an output shape (defaults to status-update) and fill its template from the computed numbers (Output shapes).
  4. Verify every numeric claim against the source before emitting, and flag any claim you can't source rather than inventing it (Verify against the source).

Ingest the run data

Accept one of three input shapes:

InputFormatSource
JUnit XMLOne or more *.xml files conforming to the JUnit XML schema (testsuite + testcase + failure / error / skipped child elements)CI runners, surefire, gradle, pytest --junitxml, jest-junit
Allure resultsDirectory of *-result.json + *-container.json per https://allurereport.org/docs/ - Allure organises results by test status (passed / failed / broken / skipped / unknown), categories, and severity levelsallure-pytest, allure-jest, allure-junit5, allure-cucumber, etc.
Test-management API exportTestRail run export, Xray run export, Zephyr cycle exportTest-management integration skills

If multiple inputs are supplied, merge by run-id (or by test-name + start-time if no id) before summarisation. Conflicts in pass/fail status (same test reported as passing in one source and failing in another) are flagged in the output, not silently resolved.

Compute the load-bearing numbers

Six metrics anchor every narrative. The skill computes them from the input and never invents:

MetricDefinitionWhy load-bearing
Total / passed / failed / skippedCounts per statusThe triage line
Pass ratepassed / (passed + failed); skipped excludedThe single-number health signal
Durationwall-clock from earliest start to latest endTells the reader "is this a 5-minute smoke or a 2-hour regression"
Top-N failuresThe N (default 3) longest-failing or most-recently-regressed testsThe actionable detail
New failures vs. last runTests that passed in the prior run and failed in this oneThe "what changed" answer the exec wants
Severity / category breakdownPer Allure's severity and categories taxonomy when available; otherwise omittedRisk-weighted reading of the same numbers

If the input lacks a metric (e.g., JUnit XML has no severity), the skill emits "n/a" rather than fabricating. Citation discipline matters most here - every number cited in the narrative is a number that appears in the input data.

Output shapes

The skill emits one of four narrative shapes; the shape is an explicit parameter (defaults to status-update):

  • status-update - Slack-ready, ≤3 lines: a pass/fail lead plus deltas and ownership (the Worked example below).
  • release-notes - PR / changelog bullets: results, new failures vs the prior release, coverage, performance, known-issue waivers.
  • exec-summary - one paragraph plus a 4-bullet outlook for the QBR / weekly leadership update.
  • cross-run-trend - narrative over a window of runs (last N runs / days); requires ≥5 runs.

The full fill-in template for each shape is in references/output-shapes.md.

Worked example

A nightly regression, status-update shape, from two JUnit XML files (this run + the prior run):

  • junit/results-2026-05-09.xml: 1,247 passed, 18 failed, 3 skipped -> pass rate 1247 / (1247 + 18) = 98.6%.
  • junit/results-2026-05-08.xml: pass rate 98.9% -> delta -0.3pp.
  • Duration: earliest testsuite start to latest stop = 1h 12m.
  • Top-3 failures by impact: cart.checkout.spec (timeout), auth.sso.spec (assertion), payments.refund.spec (timeout).

The banner emoji maps pass rate to :white_check_mark: ≥99% / :warning: 95 - 98.99% / :x: <95%, so 98.6% is :warning::

**:warning: 2026-05-09 nightly regression - 1,247 pass, 18 fail, 3 skipped.**
Pass rate 98.6% (-0.3pp vs Thu). Top regressions: `cart.checkout.spec` (timeout), `auth.sso.spec` (assertion), `payments.refund.spec` (timeout). Run: <build-url>.
Duration 1h 12m; investigation owners: @cart, @auth, @payments.

Every number traces back to a source before the draft is emitted:

### Audit (sources)

| Claim | Source |
|---|---|
| 1,247 / 18 / 3 | `junit/results-2026-05-09.xml` counts |
| 98.6% pass rate | computed passed / (passed + failed) |
| -0.3pp vs Thu | `junit/results-2026-05-08.xml` (98.9%) |
| Duration 1h 12m | earliest testsuite start to latest stop, same build |

Verify against the source

Before emitting, walk each numeric claim in the draft and confirm it appears in the input data - the Worked example's audit table is the concrete form (suppressible via --no-audit once the numbers are trusted). If any claim cannot be sourced (e.g., the SLO baseline isn't in the input), flag [unsourced - supply baseline] rather than inventing it.

Anti-patterns

Anti-patternWhy it failsFix
Inventing a trend ("regressions are up") with no prior-run dataManager pastes the summary; exec asks "vs what?"; manager has no answer.The Verify-against-source audit requires the prior-run source for any delta claim.
Citing severity when the input is JUnit XML (no severity field)JUnit's testcase / failure schema does not carry severity. Severity from JUnit alone is fabrication.Allure-only field; emit "n/a" for JUnit-only inputs.
Using pass-rate ≥99% as the default green threshold for a smoke suiteSmoke suites are tiny; one flake takes pass rate to ≤95%.Threshold is configurable per suite kind (smoke / regression / e2e).
Picking top-3 failures by name onlyReader cannot tell why they matter.Ranking is by failure-impact: longest-failing, most-recently-regressed, severity (when available).
Producing a release-notes shape with no link to the build / reportReader cannot drill into the data; the narrative becomes load-bearing without source.Build URL is required in the input; the skill refuses to emit a release-notes shape without it.
Drafting a cross-run-trend over 2 runsTwo data points are not a trend.The cross-run-trend shape requires ≥5 runs (see references/output-shapes.md); otherwise emit INSUFFICIENT_RUNS: 2 runs supplied, 5+ required for a trend.

Limitations

  • Tone is templated. The four shapes have fixed sentence patterns. Teams that want a more conversational style edit the output; the skill does not vary tone per audience.
  • Severity / categories require Allure or a test-management tool. JUnit XML alone does not carry severity; the skill cannot infer it from naming patterns.
  • No flake-vs-defect classification. A failure here is just "failed"; whether it is a flake, an environment-drift issue, or a real defect is the job of a separate failure-classification step. Compose the two when narrative + classification is needed.
  • No project-glossary substitution. The skill emits cart.checkout.spec verbatim; if the team's exec audience prefers human-readable suite names, an upstream alias map is required (out of scope for this skill).
  • Coverage data is optional. If the input does not include coverage, the release-notes shape omits the coverage bullet rather than fabricating numbers.

Hand-off targets

  • Coverage delta detail -> coverage-diff-reporter.
  • Per-tool tabular report -> junit-xml-analysis, allure-reports.

References

  • Allure Report documentation - results format (*-result.json, *-container.json), status taxonomy (passed / failed / broken / skipped / unknown), severity, categories: https://allurereport.org/docs/
  • JUnit XML schema reference - testsuite / testcase / failure / error / skipped element shape (the de facto interchange format used by surefire, jest-junit, pytest --junitxml): https://github.com/testmoapp/junitxml
  • ISO/IEC/IEEE 29119-3:2021 - test reporting structures (cite by stable ID; the canonical ISO page sits behind Cloudflare Turnstile).
  • ISTQB glossary - test report: https://glossary.istqb.org/en_US/term/test-report
  • ISTQB glossary - quality gate (the release-readiness milestone the summary reports against): https://glossary.istqb.org/en_US/term/quality-gate
  • PractiTest 2026 State of Testing Report - 70% use AI for test-case creation, "test factory" framing, narrative drafting as the dominant manager-layer use case: https://www.practitest.com/state-of-testing/
  • references/output-shapes.md - the full fill-in template for all four output shapes (status-update, release-notes, exec-summary, cross-run-trend).
  • junit-xml-analysis, allure-reports, coverage-diff-reporter - the per-tool parsers this skill consumes.

Output-shape templates

View source (opens in new window)

Output-shape templates

Deep reference for the test-run-summary-author SKILL.md. Consult for the full fill-in template of each of the four narrative shapes. The shape is an explicit parameter and defaults to status-update.

status-update (Slack-ready, ≤3 lines)

**:white_check_mark: 2026-05-09 nightly regression - 1,247 pass, 18 fail, 3 skipped.**
Pass rate 98.6% (-0.3pp vs Wed). Top regressions: `cart.checkout.spec` (timeout), `auth.sso.spec` (assertion), `payments.refund.spec` (timeout). Run: <build-url>.
Duration 1h 12m, +4 min vs Wed; investigation owners: @cart, @auth, @payments.

The single-line lead is the load-bearing claim; the second and third lines are deltas + ownership. :white_check_mark: / :warning: / :x: map to pass-rate ≥99% / 95 - 98.99% / <95% by default (configurable per project).

release-notes (PR / changelog form)

## QA - v3.4.0

- **Test results:** 1,247 / 1,268 tests passed (98.3%), 18 failures, 3 skipped. Full report: <build-url>.
- **New failures vs v3.3.0:** 5 (3 in cart, 2 in auth). All 5 have open issues filed; severity classified per Allure. None are blocking per the team's release-readiness gates.
- **Coverage:** 87.4% line, 78.1% branch (+0.6 / +0.4 vs v3.3.0). See `coverage-diff-reporter` for per-file delta.
- **Performance:** smoke + regression duration 1h 12m, no SLO regressions.
- **Known issues being shipped:** 3 P3 cosmetic flakes (tracked in [JIRA-1234, JIRA-1235, JIRA-1236]), waivers attached.

exec-summary (one-paragraph + bullets)

For the QBR / weekly leadership update. Three sentences plus a 4-bullet outlook:

The v3.4.0 release went through nightly regression with a 98.3% pass rate, marginally down from v3.3.0's 98.6% - driven by five new failures concentrated in cart and auth, all with open issues and assigned owners. Coverage improved (+0.6 line, +0.4 branch) and the smoke / regression duration stayed inside the 90-minute SLO. The release-readiness gate cleared with the standard 3 cosmetic-flake waivers.

- **What we ship:** v3.4.0 cleared all blocking gates.
- **What we watch:** auth.sso flakes - 2 of 5 failures share root cause; bisector running.
- **What we'd flag:** cart.checkout timeout - newly regressed since v3.3.0, possible perf change in the inventory-cache path.
- **What we'd ask of leadership:** confirm the 90-minute regression SLO is still the right ceiling; current trend is +4 minutes per release.

cross-run-trend (multi-run window, narrative)

A narrative form covering a time window (last N runs, last N days). The skill computes per-run metrics, identifies the run-over-run direction, and writes the trend in prose. This is the manager-layer complement to a tabular suite-health trend reporter - that answers "what is the suite health"; this shape answers "tell me the story over the last sprint." Requires ≥5 runs; with fewer, emit INSUFFICIENT_RUNS rather than drafting a trend from too few data points.

Related skills

allure-reports

Configures Allure Report (test-runner adapter install, `allure-results` directory wiring, `categories.json` for failure classification, `history-trend.json` retention via the copy-history-between-runs pattern), runs the Allure CLI to convert `allure-results` to a static HTML site, and uploads the report as a CI artifact. Use when the team needs richer test reporting than JUnit XML - step-level attachments, per-test history, retry tracking, and severity / epic / feature labeling across framework-agnostic adapters (pytest, Jest, JUnit, TestNG, NUnit, Mocha). As a rich static HTML report generator, it is the open-source alternative to extentreports (JVM/.NET per-test HTML narrative); for hosted cross-run flakiness analytics rather than a static per-run report use currents-integration.

cobertura-analysis

Parses Cobertura XML coverage reports (the JVM-canonical format originally from the cobertura-cobertura tool, also emitted by JaCoCo `--coverage-xml`, coverage.py `--xml`, Istanbul / Jest `cobertura` reporter, gocover-cobertura, and dotnet's `coverlet`). Walks the coverage-04 DTD structure (coverage → packages → classes → methods → lines + conditions), computes per-file deltas, and emits PR-time gating verdicts. Use when the existing CI emits Cobertura XML - typical for JVM-heavy stacks and tools that ship Cobertura as a default reporter.

coverage-diff-reporter

Builds a per-PR coverage delta report from any pair of LCOV / Cobertura / JSON coverage outputs (current run + baseline from the merge target) - emits a per-file table with line% / branch% deltas, called-out new files, hidden drops (overall +0.1pp but one file -8pp), and a single-line PR-comment summary. Use when the team has coverage in CI but needs human-readable PR feedback that points at the specific file the reviewer should focus on, not just an aggregate number.

coverage-py-analysis

Configures coverage.py for Python projects - wires `coverage run` (replacing `python` for instrumentation), enables branch coverage via the `--branch` flag or `branch = True` config, manages the `.coverage` data file (single-process and `combine` for parallel pytest-xdist runs), authors `.coveragerc` with `source` / `omit` / `fail_under`, and emits the format the downstream tool needs (`coverage report` for terminal, `coverage xml` for Cobertura, `coverage html` for human review, `coverage lcov` for SaaS, `coverage json` for programmatic post-processing). Use for any Python test stack (pytest, unittest, nose) that needs PR-time coverage signal.

currents-integration

Wires Currents.dev cross-run test analytics into a Playwright suite: installs `@currents/playwright`, authors `currents.config.ts` (env-sourced `recordKey` + `projectId`), registers `currentsReporter()`, enables trace/video/screenshot artifacts, and runs via `npx pwc` so per-test traces stream to the Currents dashboard with over-time flakiness, slowest-test, and pass-rate trends. Use when a Playwright suite needs hosted cross-run suite-health analytics; for a static per-run report use extentreports or allure-reports, and to sync results into Jira test management use zephyr-integration or xray-integration.

extentreports

Configures ExtentReports v5 for a JVM (or .NET via `extentreports-dotnet`) test run: wires `ExtentSparkReporter`, `attachReporter`, `createTest`, the `info`/`pass`/`warning`/`skip`/`fail` log chain, screenshots via `MediaEntityBuilder`, hierarchical `createNode` parent/child tests, and category/author/device labels, emitting a static HTML report alongside JUnit XML for CI artifact upload. Use when a suite on the Aventstack ExtentReports stack wants a richer per-test HTML narrative than JUnit XML gives; for code-coverage reporting use jacoco-analysis, and for hosted cross-run flakiness analytics use currents-integration.

jacoco-analysis

Configures JaCoCo for JVM projects (Java / Kotlin / Scala / Groovy) - wires the runtime agent via `jacoco-maven-plugin` `prepare-agent`, generates per-build reports (HTML / XML / CSV) via the `report` goal, gates the build via the `check` goal with element / limit / minimum rules, parses the six native counters (instructions, branches, lines, methods, classes, cyclomatic complexity), and converts JaCoCo XML to LCOV / Cobertura when downstream tools need a different format. Use when the JVM build is Maven / Gradle and the team wants the canonical JVM coverage tool - or to convert JaCoCo output for cross-language coverage aggregation.

jest-coverage-analysis

Configures Jest's built-in coverage (Istanbul-instrumented `babel` provider or V8-native `v8` provider), wires the right `coverageReporters` for downstream consumption (`lcov` for SaaS / cross-tool, `cobertura` for Jenkins, `text-summary` for terminal, `html` for human review), authors per-file `coverageThreshold` rules that focus the gate on critical paths (vs the global-only foot-gun), and parses the per-file JSON output for PR-time deltas. Use when the project tests with Jest (or Vitest, which uses the same Istanbul/V8 provider) and the team needs PR-time coverage signal that's both local-runnable and CI-gateable.

junit-xml-analysis

Parses JUnit-format XML reports (the de-facto interchange format every CI ingests - Jenkins, GitHub Actions, GitLab, Buildkite, CircleCI) into structured, machine-readable per-suite and per-case metrics tables (passed / failed / errored / skipped, time, classname, message, stack), groups failures by classname for trend analysis, and distinguishes "new failures vs flakes" by cross-referencing the `flakyFailure` and `rerunFailure` rerun elements. Use when the downstream consumer is a dashboard, script, or aggregator - not when the goal is a human-readable prose summary (use test-run-summary-author for that). Single-run, in-XML aggregation only; for cross-run cross-environment roll-ups, use a cross-run test-suite aggregator.

lcov-analysis

Parses LCOV `.info` text files (the de-facto coverage interchange format produced by gcov, llvm-cov, Coverage.py via `py2lcov`, JaCoCo via `xml2lcov`, Devel::Cover, Jest via `lcov` reporter, NYC, and most others). Extracts per-file line / function / branch metrics from the canonical record keywords (TN/SF/FN/FNDA/FNF/FNH/BRDA/BRF/BRH/DA/LH/LF), computes the diff vs a baseline, and emits per-file gating verdicts. Use for PR coverage gates that don't depend on a specific language runtime.

test-coverage-targeter

Builds a "what to test next" recommendation by combining a coverage report (LCOV / Cobertura / coverage.py JSON / Jest JSON / JaCoCo XML) with the PR's `git diff`, ranking uncovered branches by risk × cost - risk weighted by McCabe cyclomatic complexity and code-churn frequency, cost weighted by the unit-test pyramid layer (unit tests cheaper than integration than E2E). Emits a prioritized list with concrete file:line targets and the test layer recommended for each. Use when a team has the budget to write 5 - 10 new tests and needs help picking which uncovered code to target first instead of blindly chasing 100% coverage.

testrail-integration

Syncs test runs / results / cases between an automated test suite and TestRail (Gurock / Idera) - opens a Test Run for the build (`add_run`), batches per-case results back via `add_results_for_cases` (preferred over per-test `add_result_for_case` - N+1 API calls vs 1), maps the test framework's pass/fail/skip to TestRail status IDs, and attaches build URL + version + elapsed time. Use when the team's test management is standalone TestRail (not a Jira app) and automated suites must update it without a human copy-paste step; when the TCM is instead a Jira app use xray-integration (Xray) or zephyr-integration (Zephyr Scale), and for hosted cross-run flakiness analytics rather than TCM sync use currents-integration.

xray-integration

Imports CI test results into Xray for Jira - authenticates via the `client_id` + `client_secret` → JWT exchange (Cloud) or PAT / Basic (Server), posts to the format-specific `/api/v2/import/execution/*` endpoint (`/junit` for JUnit XML, `/cucumber` for Cucumber JSON, `/nunit` / `/testng` / `/robot` for the others), and maps automated results to existing Xray Test issues via the `xray-junit-extensions` `@XrayTest(key="...")` annotation. Use when the team uses the Xray Jira app to manage Test, Test Set, and Test Execution issue types and CI must keep those execution issues in sync; for the other Jira TCM app use zephyr-integration (Zephyr Scale), for standalone non-Jira TestRail use testrail-integration, and for hosted cross-run flakiness analytics rather than TCM sync use currents-integration.

zephyr-integration

Syncs automated test results to Zephyr Scale for Jira (formerly TM4J / SmartBear / Adaptavist): picks the product variant (Scale Cloud / Squad / Enterprise), authenticates with a long-lived API token as a Bearer header, opens a Test Cycle per build, posts executions via `POST /testexecutions` (or bulk JUnit via `/automations/executions/junit`), and maps test methods to Zephyr Test Cases via `@TestCaseKey`-style annotations. Use when the team's Jira test management is Zephyr Scale; for the Xray Jira app use xray-integration, for standalone TestRail use testrail-integration, and for over-time flakiness analytics rather than TCM sync use currents-integration.