Skip to content
Allure report logoAllure Report
Main Navigation ModulesDocumentationStarter Project

English

Español

English

Español

Appearance

Sidebar Navigation

Allure 3

Install & Upgrade

Install Allure

Upgrade Allure

Configure

Create Reports

How to generate a report

How to view a report

Improving readability of your test reports

Improving navigation in your test report

Reading Allure charts

Migrate from Allure 2

Allure 2

Install & Upgrade

Install for Windows

Install for macOS

Install for Linux

Install for Node.js

Upgrade Allure

Create Reports

How to generate a report

How to view a report

Improving readability of your test reports

Improving navigation in your test report

Features

Agent Mode

Test steps

Attachments

Test statuses

Assertion diffs

Sorting and filtering

Environments

Multistage Builds

Categories

Visual analytics

Test stability analysis

History and retries

Self-hosted storage

Quality Gate

Global Errors and Attachments

Timeline

Export to CSV

Export metrics

Guides

JUnit 5 parametrization

JUnit 5 & Selenide: screenshots and attachments

JUnit 5 & Selenium: screenshots and attachments

Setting up JUnit 5 with GitHub Actions

Pytest parameterization

Pytest & Selenium: screenshots and attachments

Pytest & Playwright: screenshots and attachments

Pytest & Playwright: videos

Playwright parameterization

Publishing Reports to GitHub Pages

Deploying Self-Hosted Storage with Docker

Deploying Self-Hosted Storage on Cloudflare Workers

Allure Report 3: XCResults Reader

How it works

Overview

Glossary

Test result file

Container file

Categories file

Environment file

Executor file

History files

Test Identifiers

Integrations

Azure DevOps

Bamboo

GitHub Action

Gradle

Jenkins

JetBrains IDEs

Maven

TeamCity

Visual Studio Code

Frameworks

AVA

Getting started

Configuration

Reference

Axios

Getting started

Configuration

Reference

Behat

Getting started

Configuration

Reference

Behave

Getting started

Configuration

Reference

Bun

Getting started

Configuration

Reference

Chai

Getting started

Reference

Codeception

Getting started

Configuration

Reference

CodeceptJS

Getting started

Configuration

Reference

Cucumber.js

Getting started

Configuration

Reference

Cucumber-JVM

Getting started

Configuration

Reference

Cucumber.rb

Getting started

Configuration

Reference

Cypress

Getting started

Configuration

Reference

Dart and Flutter

Getting started

Configuration

Reference

Diesel

Getting started

Configuration

Reference

Fetch

Getting started

Configuration

Reference

Go

Getting started

Configuration

Reference

Jasmine

Getting started

Configuration

Reference

JBehave

Getting started

Configuration

Reference

Jest

Getting started

Configuration

Reference

JUnit 4

Getting started

Configuration

Reference

JUnit 5

Getting started

Configuration

Reference

Mocha

Getting started

Configuration

Reference

Newman

Getting started

Configuration

Reference

Node.js Test Runner

Getting started

Configuration

Reference

NUnit

Getting started

Configuration

Reference

PHPUnit

Getting started

Configuration

Reference

Playwright

Getting started

Configuration

Reference

Playwright Java

Getting started

Configuration

Reference

pytest

Getting started

Configuration

Reference

Pytest-BDD

Getting started

Configuration

Reference

Reqnroll

Getting started

Configuration

Reference

Reqwest

Getting started

Configuration

Reference

REST Assured

Getting started

Configuration

Robot Framework

Getting started

Configuration

Reference

Rust Cargo Test

Getting started

Configuration

Reference

RSpec

Getting started

Configuration

Reference

Selenide

Getting started

Configuration

Reference

Selenium BiDi

Getting started

Configuration

Reference

SpecFlow

Getting started

Configuration

Reference

Spock

Getting started

Configuration

Reference

TestCafe

Getting started

Configuration

Reference

TestNG

Getting started

Configuration

Reference

Vitest

Getting started

Configuration

Reference

WebdriverIO

Getting started

Configuration

Reference

xUnit.net

Getting started

Configuration

Reference

On this page

Rust Cargo Test reference ​

These are the main building blocks you can use to integrate Rust tests with Allure by using allure-cargotest.

Macros ​

#[allure_test] ​

Supported forms:

  • #[allure_test]
  • #[allure_test(name = "Login works")]
  • #[allure_test(id = "AUTH-1")]
  • #[allure_test(doc = false)]
  • #[allure_test(name = "Login works", id = "AUTH-1")]

Use the macro together with #[test]:

rust
use allure_cargotest::allure_test;

#[allure_test(name = "Login works", id = "AUTH-1")]
#[test]
fn login_works() {
    allure.feature("Authentication");
    allure.story("Login with username and password");
}

What the macro does:

  • initializes the reporter by using ALLURE_RESULTS_DIR or target/allure-results,
  • injects an allure facade into the test body,
  • starts and stops the test lifecycle automatically,
  • applies the default labels described in Configuration,
  • derives suite labels from module_path!(),
  • uses the function's Rust doc comment as the default markdown description, unless doc = false is set or description(...) is called in the test body.

Behavior notes:

  • #[allure_test] supports both synchronous functions and async fn; compose it with a runtime-specific test macro such as #[tokio::test] placed below it (allure-cargotest does not depend on Tokio itself),
  • besides (), test functions may return Result<T, E> (where T is itself a supported return type), ExitCode, or any other type implementing std::process::Termination; Err values and unsuccessful termination values are reported to Allure before Cargo interprets the result,
  • #[should_panic] is supported only for tests that return (),
  • #[should_panic(expected = "...")] marks the test as passed only when the panic message contains the expected substring,
  • a panic inside the test body is always reported failed, regardless of its message — broken is only produced by a returned Result::Err, an unsuccessful ExitCode, or an unsuccessful custom Termination value (see the return-type bullet above), never by panicking.

#[step] ​

Supported forms:

  • #[step]
  • #[step(name = "Open login page")]

Use #[step] on helper functions that you want to render as steps in the report:

rust
use allure_cargotest::{allure_test, step};

#[step(name = "Open login page")]
fn open_login_page() {
    // ...
}

#[allure_test]
#[test]
fn login_works() {
    open_login_page();
}

When the function runs inside an active Allure test, the integration starts and stops a step automatically. Outside an active Allure context, the function behaves like a normal Rust function.

Runtime facade API ​

Inside #[allure_test], the allure facade provides methods for the most common reporting tasks.

Metadata and labels ​

  • allure.description(text)
  • allure.description_html(html)
  • allure.label(name, value)
  • allure.labels([(name, value), ...])
  • allure.owner(value)
  • allure.severity(value)
  • allure.layer(value)
  • allure.tag(value)
  • allure.tags(["smoke", "auth"])
  • allure.id(value)

Example:

rust
use allure_cargotest::allure_test;

#[allure_test]
#[test]
fn login_works() {
    allure.description("Checks that a valid user can sign in.");
    allure.owner("John Doe");
    allure.severity("critical");
    allure.label("microservice", "ui");
    allure.tags(["smoke", "auth"]);
}

Identity and display ​

  • allure.display_name(name) — overrides the name shown in the report, independent of #[allure_test(name = "...")], for when the display name has to be computed at runtime
  • allure.history_id(value) — overrides the identifier Allure uses to match this result against previous runs for retry/flaky/history tracking (by default derived from the full test name and non-excluded parameters)
  • allure.test_case_id(value) — overrides the identifier Allure uses to group results into one logical test case across environments (by default derived from the full test name)

Example:

rust
use allure_cargotest::allure_test;

#[allure_test]
#[test]
fn login_works() {
    allure.display_name("Login works (computed at runtime)");
    allure.history_id("login-works-stable-id");
    allure.test_case_id("AUTH-LOGIN-001");
}

Hierarchies ​

  • allure.epic(value)
  • allure.feature(value)
  • allure.story(value)
  • allure.parent_suite(value)
  • allure.suite(value)
  • allure.sub_suite(value)

Example:

rust
use allure_cargotest::allure_test;

#[allure_test]
#[test]
fn login_works() {
    allure.epic("Web interface");
    allure.feature("Authentication");
    allure.story("Login with username and password");

    allure.parent_suite("UI tests");
    allure.suite("Authentication");
    allure.sub_suite("Positive scenarios");
}

Links and parameters ​

  • allure.link(url, Some(name), Some(link_type))
  • allure.links([(url, Some(name), Some(link_type)), ...])
  • allure.issue(name, url)
  • allure.tms(name, url)
  • allure.parameter(name, value)
  • allure.parameter_excluded(name, value, excluded) — excluded: true keeps the parameter visible in the report without letting it affect the history/retry identity computed from parameters
  • allure.parameter_mode(name, value, mode) — a ParameterMode from allure_rust_commons: Masked shows the name but hides the value (for secrets), Hidden removes the parameter from the report entirely, Default is the normal display
  • allure.parameter_with_options(name, value, excluded, mode) — combines both controls in one call

Example:

rust
use allure_cargotest::allure_test;
use allure_rust_commons::ParameterMode;

#[allure_test]
#[test]
fn login_works() {
    allure.issue("AUTH-123", "https://jira.example.com/browse/AUTH-123");
    allure.tms("TMS-456", "https://tms.example.com/cases/TMS-456");
    allure.parameter("browser", "firefox");
    allure.parameter_mode("password", "hunter2", ParameterMode::Masked);
    allure.parameter_excluded("sessionToken", "zzz-123", true);
}

Attachments ​

  • allure.attachment(name, content_type, body)
  • allure.attachment_path(name, content_type, path) — reads the attachment body from a file
  • allure.attach_trace(path) / allure.attach_trace_named(name, path) — attaches an existing Playwright trace archive (a convenience wrapper around attachment_path using the application/vnd.allure.playwright-trace content type, so Allure's trace viewer opens it instead of offering a plain zip download; attach_trace defaults the attachment name to trace.zip) — does not generate traces or depend on Playwright itself

Example:

rust
use allure_cargotest::allure_test;

#[allure_test]
#[test]
fn login_works() {
    allure.attachment(
        "response.json",
        "application/json",
        br#"{"status":"ok","user":"demo"}"#,
    );
    allure
        .attachment_path("server.log", "text/plain", "assets/server.log")
        .expect("failed to read the log file");
}

Run-level (global) diagnostics ​

These attach evidence to the whole test run (the report's launch/Environment level) instead of the current test. They can be called from inside #[allure_test], or on their own even when no test is currently active:

  • allure.global_attachment(name, content_type, body)
  • allure.global_attachment_path(name, content_type, path)
  • allure.global_error(message)
  • allure.global_error_with_trace(message, trace)

Example:

rust
use allure_cargotest::allure_test;

#[allure_test]
#[test]
fn login_works() {
    allure
        .global_attachment("run log", "text/plain", "shared setup output")
        .expect("failed to write the run-level attachment");
}

Steps ​

  • allure.step(name, || { ... }) runs a closure as a step and returns its value
  • allure.enter_step(name) returns a StepGuard that keeps the step open until dropped
  • allure.log_step(name)
  • allure.log_step_with(name, status, error)

Examples:

rust
use allure_cargotest::{allure_test, Status};

#[allure_test]
#[test]
fn login_works() {
    allure.step("Open login page", || {
        // ...
    });

    let mut guard = allure.enter_step("Submit credentials");
    // ...
    drop(guard);

    allure.log_step("Verify the page title");
    allure.log_step_with("Check audit log", Some(Status::Failed), Some("entry not found"));
}

StepGuard also lets you override the final step status before the guard is dropped, with fail or the more general set_status:

rust
use allure_cargotest::allure_test;

#[allure_test]
#[test]
fn login_works() {
    let mut guard = allure.enter_step("Validate response");
    guard.fail("Unexpected status code");
}

Stages ​

  • allure.stage(name) opens a new named "stage" step. Unlike step/enter_step, you don't close a stage explicitly — starting the next stage (or ending the test) automatically closes the previous one as passed. Anything recorded in between (steps, attachments, logged assertions) nests under whichever stage is currently open.

Example:

rust
use allure_cargotest::allure_test;

#[allure_test]
#[test]
fn login_works() {
    allure.stage("open login page");
    allure.log_step("login page opened");

    allure.stage("collect evidence");
    allure.attachment("page.html", "text/html", "<html>...</html>");
}

This produces two top-level steps — open login page (containing login page opened) and collect evidence (containing the page.html attachment) — without manually nesting closures.

Manual integration with CargoTestReporter ​

If macros are not enough for your test harness, you can use CargoTestReporter directly:

rust
use allure_cargotest::CargoTestReporter;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let reporter = CargoTestReporter::new("target/allure-results")?;

    reporter.run_test("login_works", |allure| {
        allure.feature("Authentication");
        allure.parameter("browser", "firefox");
    });

    Ok(())
}

Useful methods:

  • CargoTestReporter::new(results_dir)
  • run_test(name, |allure| { ... })
  • run_test_with_metadata(test_name, full_name, allure_id, tags, |allure| { ... })
  • run_test_with_result(name, |allure| { ... })
  • is_selected(test_name, full_name, allure_id, tags)

run_test_with_metadata and is_selected are the only entry points that forward an explicit allure_id/tags pair into test-plan matching, so id entries in an ALLURE_TESTPLAN_PATH file only take effect for integrations built on CargoTestReporter directly — not for #[allure_test(id = "...")], which currently only participates in selector matching.

Building a custom integration with allure-rust-commons ​

Use allure-rust-commons when you need low-level control over the lifecycle:

rust
use allure_rust_commons::{
    AllureRuntime, FileSystemResultsWriter, StartTestCaseParams, Status,
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let writer = FileSystemResultsWriter::new("target/allure-results")?;
    let runtime = AllureRuntime::new(writer);
    let lifecycle = runtime.lifecycle();

    lifecycle.start_test_case(
        StartTestCaseParams::new("login_works").with_full_name("auth::login_works"),
    );
    lifecycle.stop_test_case(Status::Passed, None);

    Ok(())
}

The main low-level types are:

  • AllureRuntime
  • AllureLifecycle
  • StartTestCaseParams
  • FileSystemResultsWriter
  • Status and StatusDetails
  • the model types exported from allure_rust_commons::model
Pager
Previous pageConfiguration
Next pageGetting started
Powered by

Subscribe to our newsletter

Get product news you actually need, no spam.

Subscribe
Allure TestOps
  • Overview
  • Why choose us
  • Cloud
  • Self-hosted
  • Success Stories
Company
  • Documentation
  • Blog
  • About us
  • Contact
  • Events
© 2026 Qameta Software Inc. All rights reserved.
A Markdown version of this page is available at /docs/rust-reference.md