---
title: Gradle integration
description: Learn how to integrate Allure Report with Gradle. Apply the plugin, configure Allure 3 or Allure 2 runtimes, autoconfigure test framework adapters, and generate reports locally and in CI.
---

# Gradle integration

The Allure Gradle plugin generates Allure reports from the raw results produced by your test tasks. It handles downloading the Allure CLI, instrumenting test tasks to write results, and providing tasks for generating and serving reports.

- Requires Gradle 8.11 or newer
- Requires Java 17 or newer

## Setting up

Apply the umbrella plugin in your `build.gradle.kts`:

```kotlin
plugins {
    id("io.qameta.allure") version "4.1.0"
}

repositories {
    // Required so Gradle can resolve allure-java adapter dependencies
    mavenCentral()
}
```

Or in Groovy DSL (`build.gradle`):

```groovy
plugins {
    id 'io.qameta.allure' version '4.1.0'
}

repositories {
    mavenCentral()
}
```

The `io.qameta.allure` plugin is a shortcut that applies both `io.qameta.allure-adapter` and `io.qameta.allure-report` together. Apply them separately if you need finer control (see [Plugin breakdown](#plugin-breakdown)).

## Generating a report

### View the report locally

```shell
./gradlew allureServe
```

Opens the report in a local web server. By default it does not run your tests first.

### Run tests and view the report

```shell
./gradlew allureServe --depends-on-tests
```

### Generate a static report

```shell
./gradlew allureReport
```

Output: `build/reports/allure-report/allureReport/`

When using the extension `reportDir`, the output subdirectory is always named after the task (`allureReport`, `allureAggregateReport`, etc.), so the aggregate report lands at `build/reports/allure-report/allureAggregateReport/`. When using the `--report-dir` flag, the report is written directly to the specified path with no task-name subdirectory added.

### Run tests and generate a report in one command

```shell
./gradlew allureReport --depends-on-tests
```

## Tasks added by the plugin

| Task                    | Description                                                                                     |
| ----------------------- | ----------------------------------------------------------------------------------------------- |
| `allureReport`          | Generates a static HTML report                                                                  |
| `allureServe`           | Generates a report and opens it in a local web server                                           |
| `allureAggregateReport` | Generates an aggregate report across subprojects (requires `io.qameta.allure-aggregate-report`) |
| `allureAggregateServe`  | Serves an aggregate report (requires `io.qameta.allure-aggregate-report`)                       |
| `downloadAllure`        | Downloads and caches the Allure CLI                                                             |

## Selecting the Allure version

Set `allure.version` to choose the runtime:

```kotlin
allure {
    version = "3.9.0"   // Allure 3 (default)
    // version = "2.42.1"  // Allure 2
}
```

- Version `3.x` → Allure 3 (Node.js-based, provisioned automatically)
- Version `2.x` → Allure 2 (`allure-commandline` zip, downloaded from Maven Central)
- Default when unset: Allure 3, version `3.9.0`

Any version string whose major number is 3 or higher selects Allure 3; major number 2 or lower selects Allure 2.

## Allure 3 runtime provisioning

For Allure 3, the plugin provisions a private Node.js runtime automatically. You do **not** need Node.js installed on your machine.

On first use, the plugin downloads Node.js and installs the `allure` npm package. The Node.js download is cached by Gradle and skipped on subsequent builds. The npm install runs again on a fresh checkout.

## Test framework autoconfiguration

When you apply `io.qameta.allure-adapter`, the plugin scans your test classpath and automatically adds the matching allure-java adapter. No manual dependency declaration is needed for supported frameworks.

Supported frameworks and their activation triggers:

| Framework DSL name | Activates when this is on the classpath                                                                                                                                      |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `junit4`           | `junit:junit`                                                                                                                                                                |
| `junit5`           | `org.junit.jupiter:junit-jupiter-api`                                                                                                                                        |
| `junitPlatform`    | `org.junit.platform:junit-platform-launcher`                                                                                                                                 |
| `testng`           | `org.testng:testng` (6.14.3+)                                                                                                                                                |
| `assertj`          | `org.assertj:assertj-core`                                                                                                                                                   |
| `jbehave`          | `org.jbehave:jbehave-core` (4.x)                                                                                                                                             |
| `jbehave5`         | `org.jbehave:jbehave-core` (5.x)                                                                                                                                             |
| `karate`           | `com.intuit.karate:karate-core`                                                                                                                                              |
| `scalatest`        | `org.scalatest:scalatest_2.12` or `scalatest_2.13`                                                                                                                           |
| `spock`            | `org.spockframework:spock-core` (uses `allure-spock2`; requires `useJUnitPlatform()` on the test task — without it, the adapter is on the classpath but captures no results) |
| `cucumber4Jvm`     | `io.cucumber:cucumber-core` (4.x)                                                                                                                                            |
| `cucumber5Jvm`     | `io.cucumber:cucumber-core` (5.x)                                                                                                                                            |
| `cucumber6Jvm`     | `io.cucumber:cucumber-core` (6.x)                                                                                                                                            |
| `cucumber7Jvm`     | `io.cucumber:cucumber-core` (7.x)                                                                                                                                            |

The default allure-java version used for all adapters is `2.35.2`. AspectJ weaver version is `1.9.25.1`.

### What autoconfiguration does

When a supported framework is detected:

- Adds the allure adapter dependency to the test compile and runtime classpath
- Adds the AspectJ weaver agent to the JVM arguments of all `Test` and `JavaExec` tasks (enables `@Step` and `@Attachment` support)
- Adds `allure-descriptions-javadoc` to the annotation processor path (enables `@Description` from Javadoc)
- Configures default test listeners where applicable (`junit5`, `junitPlatform`, `testng`, `karate`)

### Disabling autoconfiguration

To turn off all autoconfiguration:

```kotlin
allure {
    adapter {
        autoconfigure.set(false)
    }
}
```

To turn off individual parts:

```kotlin
allure {
    adapter {
        autoconfigureListeners.set(false)         // don't register default listeners
        autoconfigureJavadocDescriptions.set(false) // don't add the Javadoc annotation processor
        aspectjWeaver.set(false)                  // don't add AspectJ agent
    }
}
```

To disable listeners for a specific framework only:

```kotlin
allure {
    adapter {
        frameworks {
            junit5 {
                autoconfigureListeners.set(false)
            }
        }
    }
}
```

### Explicitly listing frameworks

If you have multiple test frameworks on the classpath but only want to instrument one:

```kotlin
allure {
    adapter {
        frameworks {
            junit5
            // only junit5 will be configured; others are ignored
        }
    }
}
```

Listing any framework explicitly in `frameworks {}` switches the plugin from fully-automatic mode to selective mode: only the adapters you name here are registered, and the automatic registration of all other adapters is suppressed. Each listed adapter is still activation-gated — its dependency is added only when the trigger dependency is detected on the classpath, so there is no cost if the trigger is absent.

## Configuration reference

### Adapter options

```kotlin
allure {
    adapter {
        // allure-java adapter version for all frameworks
        allureJavaVersion.set("2.35.2")

        // AspectJ weaver version
        aspectjVersion.set("1.9.25.1")

        // Where test tasks write raw Allure results
        resultsDir.set(layout.buildDirectory.dir("allure-results"))

        // Path to categories.json for Allure 2 (auto-detected from test/resources by default)
        categoriesFile.set(layout.projectDirectory.file("config/categories.json"))
    }
}
```

### Report options

```kotlin
allure {
    report {
        // Base directory for all reports (each task gets its own subdirectory named after the task)
        reportDir.set(layout.buildDirectory.dir("my-reports"))

        // Generate a single self-contained HTML file instead of a directory
        singleFile.set(true)

        // Custom Allure 3 config file
        configFile.set(layout.projectDirectory.file("allurerc.mjs"))
    }
}
```

### Environment variables for the Allure CLI

```kotlin
allure {
    environment.put("JAVA_HOME", "/path/to/java_home")
}
```

## Task-level options (command line)

Options shared by both `allureReport` and `allureServe`:

```shell
# Run test tasks before generating the report
./gradlew allureReport --depends-on-tests
./gradlew allureServe --depends-on-tests
```

To make `dependsOnTests` permanent without the flag, configure it at the task level:

```kotlin
tasks.named<io.qameta.allure.gradle.report.tasks.AllureReport>("allureReport") {
    dependsOnTests()
}
```

```shell

# Use a custom Allure 3 config file (Allure 3 only)
./gradlew allureReport --config-file=allurerc.mjs
./gradlew allureServe --config-file=allurerc.mjs

```

Options specific to `allureReport`:

```shell
# Generate a single-file report
./gradlew allureReport --single-file=true

# Output to a specific directory
./gradlew allureReport --report-dir=build/my-report

# Delete the report directory before generating
./gradlew allureReport --clean
```

Options specific to `allureServe`:

```shell
# Bind server to a specific port
./gradlew allureServe --port=8080

# Bind server to a specific host address (Allure 2 only)
./gradlew allureServe --host=192.168.1.10
```

`--host` is not supported for Allure 3. Use `--port` only, or set `allure.version` to a `2.x` release if you need host binding.

For Allure 3, `--port` is passed to the `allure open` subcommand (Allure 3 uses `generate` + `open` internally rather than a persistent `serve` process).

## Custom results directory

By default, raw results go to `build/allure-results`. To change this:

```kotlin
allure {
    adapter {
        resultsDir.set(layout.buildDirectory.dir("custom-allure-results"))
    }
}
```

## Single-file report

To produce a self-contained HTML file instead of a directory:

```kotlin
allure {
    report {
        singleFile.set(true)
    }
}
```

Or for a one-off run:

```shell
./gradlew allureReport --single-file=true
```

This works for both Allure 2 and Allure 3. For `allureServe`, `singleFile` has no effect.

## Allure 3 configuration file

For Allure 3, you can provide a custom config file to control report name, theme, environments, grouping, and plugins:

```kotlin
allure {
    report {
        configFile.set(layout.projectDirectory.file("allurerc.mjs"))
    }
}
```

Or per-invocation:

```shell
./gradlew allureReport --config-file=allurerc.mjs
```

When `configFile` is set, the plugin passes `--config <your file>` to the Allure CLI and also passes `--output <reportDir>`. The `--output` flag takes precedence over any `output` field in your config file, so the report is always written to the task's `reportDir`. Allure 3 options such as `singleFile`, report name, and theme must be set in your config file; the Gradle-level `singleFile` property and `--single-file` flag are ignored when a custom `configFile` is in use.

`configFile` is not supported for Allure 2. Setting it while using a `2.x` version fails with an error.

## Multi-project builds

### Aggregate report

To generate a combined report from all subprojects, apply `io.qameta.allure-aggregate-report` to the root project and `io.qameta.allure-adapter` to each subproject that runs tests.

Root `build.gradle.kts`:

```kotlin
plugins {
    id("io.qameta.allure-aggregate-report") version "4.1.0"
}

repositories {
    mavenCentral()
}
```

Each subproject's `build.gradle.kts`:

```kotlin
plugins {
    `java`
    id("io.qameta.allure-adapter") version "4.1.0"
}
```

Then run:

```shell
./gradlew allureAggregateReport
# or view directly:
./gradlew allureAggregateServe
```

By default, `io.qameta.allure-aggregate-report` aggregates results from `allprojects` (the root project plus all subprojects). To customize which projects are included:

```kotlin
// Remove all defaults and add specific projects
configurations.allureAggregateReport.dependencies.clear()
dependencies {
    allureAggregateReport(project(":module1"))
    allureAggregateReport(project(":module2"))
}
```

### Per-module results directories

If a subproject writes results to a non-default location, configure it in that subproject:

```kotlin
allure {
    adapter {
        resultsDir.set(layout.buildDirectory.dir("my-results"))
    }
}
```

### Adding external result directories

To feed results from a directory not managed by the plugin (e.g., from a script or a non-JVM tool) into the report:

```kotlin
// In a project that applies io.qameta.allure-adapter-base:
plugins {
    id("io.qameta.allure-adapter-base") version "4.1.0"
}

dependencies {
    allureRawResultElements(files(layout.buildDirectory.dir("external-results")))
}
```

Or from the report side:

```kotlin
dependencies {
    allureReport(files(layout.buildDirectory.dir("external-results")))
}
```

## Allure 2 download customization

For Allure 2, the plugin downloads `io.qameta.allure:allure-commandline:{version}:zip` from Maven Central via Gradle dependency resolution.

### Custom download URL (air-gapped environments)

```kotlin
allure {
    version.set("2.42.1")

    commandline {
        // Patterns: [organization], [group], [module], [version]
        downloadUrlPattern.set("https://my-mirror.example.com/[group]/[module]-[version].zip")
    }
}
```

The plugin registers an exclusive Ivy repository for the resolved URL. The archive is always resolved as a zip; hardcode `.zip` in your URL pattern.

### Local allure-commandline archive

To resolve Allure 2 from a local file instead of a repository:

```kotlin
dependencies {
    allureCommandline(files("/path/to/allure-commandline.zip"))
}
```

Use an absolute path — relative paths are unreliable in multi-project builds.

## Plugin breakdown

The umbrella plugin `io.qameta.allure` is composed of smaller plugins you can apply individually:

| Plugin ID                           | What it does                                                                                                        |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `io.qameta.allure`                  | Applies `io.qameta.allure-adapter` + `io.qameta.allure-report`                                                      |
| `io.qameta.allure-adapter`          | Auto-instruments all `Test` and `JavaExec` tasks, adds allure-java adapters, AspectJ                                |
| `io.qameta.allure-adapter-base`     | Exposes `allureRawResultElements` configuration; no adapter autoconfiguration                                       |
| `io.qameta.allure-report`           | Adds `allureReport` and `allureServe` tasks for the current project                                                 |
| `io.qameta.allure-aggregate-report` | Adds `allureAggregateReport` and `allureAggregateServe` tasks; aggregates from the root project and all subprojects |
| `io.qameta.allure-download`         | Adds the `downloadAllure` task; provisions the Allure CLI                                                           |
| `io.qameta.allure-base`             | Adds the `allure {}` extension; the foundation all other plugins build on                                           |

## Using in CI

### GitHub Actions

Cache the Gradle build cache directory to avoid re-downloading the Allure CLI on every run:

```yaml
- name: Run tests and generate Allure report
  run: ./gradlew test allureReport

- name: Upload Allure report
  uses: actions/upload-artifact@v4
  with:
    name: allure-report
    path: build/reports/allure-report/allureReport/
```

To share the Gradle caches between runs (including the downloaded Allure CLI):

```yaml
- uses: gradle/actions/setup-gradle@v4
```

### Jenkins Pipeline

```groovy
pipeline {
    agent any

    stages {
        stage('Test') {
            steps {
                sh './gradlew test'
            }
        }
        stage('Report') {
            steps {
                sh './gradlew allureReport'
                publishHTML(target: [
                    reportDir: 'build/reports/allure-report/allureReport',
                    reportFiles: 'index.html',
                    reportName: 'Allure Report'
                ])
            }
        }
    }
}
```

Alternatively, if you use the [Allure Jenkins plugin](/docs/integrations-jenkins/), you can let Jenkins generate and display the report itself instead of calling `allureReport`.

### Running without running tests

In CI pipelines where tests and reporting are separate stages, you may want to run only the report task against results already written to disk:

```shell
./gradlew allureReport
```

This reads existing `build/allure-results/` without re-running tests, which is the default behavior.
