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:
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):
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).
Generating a report
View the report locally
./gradlew allureServeOpens the report in a local web server. By default it does not run your tests first.
Run tests and view the report
./gradlew allureServe --depends-on-testsGenerate a static report
./gradlew allureReportOutput: 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
./gradlew allureReport --depends-on-testsTasks 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:
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-commandlinezip, 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
TestandJavaExectasks (enables@Stepand@Attachmentsupport) - Adds
allure-descriptions-javadocto the annotation processor path (enables@Descriptionfrom Javadoc) - Configures default test listeners where applicable (
junit5,junitPlatform,testng,karate)
Disabling autoconfiguration
To turn off all autoconfiguration:
allure {
adapter {
autoconfigure.set(false)
}
}To turn off individual parts:
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:
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:
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
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
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
allure {
environment.put("JAVA_HOME", "/path/to/java_home")
}Task-level options (command line)
Options shared by both allureReport and allureServe:
# Run test tasks before generating the report
./gradlew allureReport --depends-on-tests
./gradlew allureServe --depends-on-testsTo make dependsOnTests permanent without the flag, configure it at the task level:
tasks.named<io.qameta.allure.gradle.report.tasks.AllureReport>("allureReport") {
dependsOnTests()
}
# Use a custom Allure 3 config file (Allure 3 only)
./gradlew allureReport --config-file=allurerc.mjs
./gradlew allureServe --config-file=allurerc.mjsOptions specific to allureReport:
# 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 --cleanOptions specific to allureServe:
# 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:
allure {
adapter {
resultsDir.set(layout.buildDirectory.dir("custom-allure-results"))
}
}Single-file report
To produce a self-contained HTML file instead of a directory:
allure {
report {
singleFile.set(true)
}
}Or for a one-off run:
./gradlew allureReport --single-file=trueThis 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:
allure {
report {
configFile.set(layout.projectDirectory.file("allurerc.mjs"))
}
}Or per-invocation:
./gradlew allureReport --config-file=allurerc.mjsWhen 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:
plugins {
id("io.qameta.allure-aggregate-report") version "4.1.0"
}
repositories {
mavenCentral()
}Each subproject's build.gradle.kts:
plugins {
`java`
id("io.qameta.allure-adapter") version "4.1.0"
}Then run:
./gradlew allureAggregateReport
# or view directly:
./gradlew allureAggregateServeBy default, io.qameta.allure-aggregate-report aggregates results from allprojects (the root project plus all subprojects). To customize which projects are included:
// 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:
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:
// 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:
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)
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:
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:
- 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):
- uses: gradle/actions/setup-gradle@v4Jenkins Pipeline
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, 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:
./gradlew allureReportThis reads existing build/allure-results/ without re-running tests, which is the default behavior.