Testland
Browse all skills & agents

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.

Install with skills.sh (any agent)

npx skills add testland/qa --skill allure-reports
View source

allure-reports

Overview

Allure Report is "an open-source framework-agnostic test result visualization tool" that "transforms test execution data into clear, interactive HTML reports" (allure-docs (opens in new window)). It "supports testing frameworks across JavaScript, Python, Java, C#, PHP, and Ruby" with 30+ adapters (allure-docs (opens in new window)).

Allure's two-stage workflow:

  1. Tests run with an Allure adapter installed. The adapter writes per-test JSON files into an allure-results/ directory.
  2. Allure CLI generates the static HTML site from allure-results/, optionally merging in history from a previous run for trend graphs.

The two artifacts are kept separate intentionally: results are runner-emitted; the report is a static deliverable.

When to use

  • The team needs richer reporting than JUnit XML - per-step attachments, screenshots on failure, history trends, severity / epic / feature labels, custom categorization of failures.
  • A multi-framework project (pytest + Jest + JUnit) needs one unified report instead of three separate ones.
  • An air-gapped or compliance-restricted environment needs static HTML output (vs SaaS test-management).

If the team only needs JUnit pass/fail and the CI already surfaces that, see junit-xml-analysis - that's a much lighter dependency.

Step 1 - Install the framework adapter

Each runner has a per-language adapter that writes to allure-results/. Examples:

FrameworkPackage / coordinateOutput dir env var (typical)
pytestpip install allure-pytest--alluredir=allure-results
Jestnpm i -D allure-jestoutputFolder config
Mochanpm i -D allure-mochaoutputFolder config
JUnit 5org.junit.platform:junit-platform-launcher + io.qameta.allure:allure-junit5allure.results.directory system property
TestNGio.qameta.allure:allure-testngallure.results.directory
NUnit / xUnitNuGet Allure.NUnit / Allure.XunitallureConfig.json directory

Adapter docs are at the framework-specific subpaths under allurereport.org/docs/ (allure-docs (opens in new window)).

The output of running tests with the adapter installed is a directory of per-test JSON files (<uuid>-result.json, <uuid>-container.json, plus attachment-<uuid>.<ext> files for screenshots / logs).

Step 2 - Generate the static report

Install the Allure CLI (allure-docs (opens in new window) linked from "Installation"):

# Node-based (cross-platform):
npm install -g allure-commandline
# Or via Scoop / Homebrew / apt - see allurereport.org/docs/ install pages.

Generate from the results directory:

allure generate allure-results --clean -o allure-report

--clean removes the previous allure-report/ before regenerating; -o sets the output dir.

To preview locally:

allure open allure-report

Or in one shot (useful in dev - runs a temp server with a freshly generated report):

allure serve allure-results

(See allurereport.org/docs/ for the CLI reference; specific flags have evolved across Allure 2.x and Allure 3 - pin a version in CI to avoid drift.)

Step 3 - Configure failure categories

Per allure-categories (opens in new window), categories.json placed in allure-results/ defines custom failure classification. Each entry matches by message regex, trace regex, and result statuses (failed, broken, passed, skipped, unknown):

[
  {
    "name": "Ignored tests",
    "messageRegex": ".*ignored.*",
    "matchedStatuses": ["skipped"]
  },
  {
    "name": "Infrastructure problems",
    "messageRegex": ".*RuntimeException.*",
    "matchedStatuses": ["broken"]
  }
]

Per allure-categories (opens in new window), category objects also support traceRegex (matches against stack trace) and flaky (boolean) to mark a category as flaky-by-default.

"The array order determines the matching sequence Allure applies when categorizing test results." (allure-categories (opens in new window))

So order from most-specific to least-specific. A "DB connection refused" category should precede a generic "Infrastructure" category.

Step 4 - Wire history retention

Per allure-history (opens in new window), history is what drives the trends panel ("first failed", "last passed", flake / retry rate over time):

"Allure Report uses a history ID to link test results across multiple runs. This identifier is automatically calculated based on the test's fully-qualified name and its parameters."

For Allure 2 (the broadly-deployed version), enabling history is manual (allure-history (opens in new window)):

  1. Generate your initial report in the allure-report directory
  2. Remove the allure-results directory
  3. Run tests
  4. Copy allure-report/history subdirectory to allure-results/history
  5. Generate the next report

In CI, that becomes:

# Before running tests
mkdir -p allure-results
if [ -d previous-allure-report/history ]; then
  cp -r previous-allure-report/history allure-results/
fi

# Run tests (writes to allure-results/)
npm test

# Generate
allure generate allure-results --clean -o allure-report

# Save the history slice for next time
# (Upload allure-report/ as an artifact; download into previous-allure-report/ on next run.)

Per allure-history (opens in new window): "If you follow such a routine regularly, Allure will each time keep data from up to 20 latest reports in allure-results/history."

For Allure 3 (allure-history (opens in new window)):

"Allure 3 simplifies this by using a single JSONL history file. You configure it in your settings file with a historyPath parameter."

Step 5 - Distinguish retries from history

Per allure-history (opens in new window):

"Retries: Multiple runs of the same test within a single launch (same allure-results directory)."

"History: Links to the same test across different launches, enabling trend analysis and stability tracking."

Don't clear allure-results between retries within a run - that collapses retry data. Do clear it between launches (different commits / runs) - only history/ subdir is preserved.

Step 6 - CI integration (GitHub Actions)

# .github/workflows/test-with-allure.yml
name: test-with-allure
on:
  pull_request:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: actions/setup-node@v4
        with: { node-version: '20' }

      - name: Restore previous Allure history
        uses: actions/download-artifact@v4
        with:
          name: allure-history
          path: previous-allure-report
        continue-on-error: true   # First run on a branch has no history

      - name: Seed history into results dir
        run: |
          mkdir -p allure-results
          if [ -d previous-allure-report/history ]; then
            cp -r previous-allure-report/history allure-results/
          fi

      - name: Run tests with Allure adapter
        run: npm test    # adapter writes to allure-results/

      - name: Install Allure CLI
        run: npm install -g allure-commandline

      - name: Generate report
        if: always()
        run: allure generate allure-results --clean -o allure-report

      - name: Upload report
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: allure-report
          path: allure-report
          retention-days: 30

      - name: Save history for next run
        if: always() && github.ref == 'refs/heads/main'
        uses: actions/upload-artifact@v4
        with:
          name: allure-history
          path: allure-report/history
          retention-days: 90

if: always() on the report-generation steps is critical - Allure matters most on failure.

For Allure history hosted on GitHub Pages, the simple-elf/allure-report-action GitHub Action automates the publish-to-Pages workflow (third-party, not first-party Allure tooling).

Step 7 - Add metadata to test cases

Allure's value compounds with metadata. The adapter exposes per-language helpers; the canonical labels are severity (blocker / critical / normal / minor / trivial), epic / feature / story (for BDD-style grouping), and owner.

# pytest example
import allure

@allure.severity(allure.severity_level.CRITICAL)
@allure.epic('Checkout')
@allure.feature('Promo codes')
@allure.story('Apply at checkout')
def test_apply_promo_lowercase():
    ...
// Jest / Mocha example
import { allure } from 'allure-jest';

allure.severity('critical');
allure.epic('Checkout');
allure.feature('Promo codes');

Severity drives the "blocker" / "critical" filter on the report's overview; epic / feature / story drive the BDD-grouped view. Without them, the report is a flat list - usable but missing Allure's main selling point.

Anti-patterns

Anti-patternWhy it failsFix
Skipping the history stepTrends panel is empty; retry/flake history can't be tracked across runs.Wire the copy-history pattern (Step 4) per allure-history (opens in new window).
Clearing allure-results mid-runRetry information is lost - retries appear as separate failed launches.Clear only between launches; preserve history/ subdir per allure-history (opens in new window).
categories.json ordered least-specific firstGeneric "Infrastructure" category catches everything; specific categories never match.Order most-specific first per allure-categories (opens in new window).
Allure as a substitute for JUnit XML in PR gatingAllure's report is for humans, not gating; JUnit XML is the gate.Emit both; gate on JUnit; surface Allure as artifact.
One Allure adapter version + a different CLI versionSchema drift between adapter (results writer) and CLI (results reader); empty / corrupt report.Pin both to compatible versions; bump together per allure-docs (opens in new window).
Adapter installed but no metadataReport is a flat pass/fail list - same value as JUnit XML.Add severity / epic / feature / story (Step 7).
Treating <uuid>-result.json files as durableThe file naming and schema are per-Allure-version internal contracts.Don't post-process raw allure-results/ files; consume the generated allure-report/data/*.json instead.

Limitations

  • No PR-coverage role. Allure tells you which tests passed / failed / flaked; it doesn't measure code coverage. Pair with lcov-analysis / cobertura-analysis / jacoco-analysis.
  • History is per-CI-runner-local unless explicitly persisted. GitHub Actions artifacts have a retention cap (default 90 days); for long-running history, consider GitHub Pages or S3 hosting.
  • Allure 2 vs Allure 3 (allure-history (opens in new window)) - Allure 2 is "stable, mature version with broader integrations"; Allure 3 is the rebuild. Many adapters still target 2.x. Don't mix versions.
  • Adapter feature parity varies. Java adapters tend to be the reference; some JS / Python adapters lag behind on step-attachment APIs. Check the per-adapter docs.

References

  • allure-docs (opens in new window) - overview, framework-agnostic positioning, supported language list, navigation root.
  • allure-history (opens in new window) - history ID mechanism, copy-history-between-runs routine for Allure 2, Allure 3 JSONL pattern, retries vs history distinction.
  • allure-categories (opens in new window) - categories.json schema (name, messageRegex, traceRegex, matchedStatuses, flaky), matching order, sample.
  • junit-xml-analysis - leaner alternative when only pass/fail + flake detection is needed.
  • coverage-diff-reporter, lcov-analysis, cobertura-analysis - coverage side of the same PR review.

Related skills

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.

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.

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.