Official Allure Framework libraries for generating Allure Report results in Rust.
- Learn more about Allure Report at https://allurereport.org
- π Documentation β discover official documentation for Allure Report
- β Questions and Support β get help from the team and community
- π’ Official annoucements β be in touch with the latest updates
- π¬ General Discussion β engage in casual conversations, share insights and ideas with the community
allure-rust is the Rust implementation of the Allure Framework. It provides primitives to build
Allure-compatible results and a ready-to-use integration for cargo test.
This workspace currently includes:
allure-rust-commons: core runtime model, lifecycle, writer, and facade APIs.allure-cargotest: test integration helper and reporter forcargo test.allure-test-macros: procedural macro crate that provides#[allure_test]and#[step].
For regular Rust tests with automatic lifecycle wiring:
cargo add allure-cargotest --devFor building your own integration/framework adapter:
cargo add allure-rust-commonsBy default, results are written to target/allure-results.
You can override it with:
ALLURE_RESULTS_DIR=./allure-results cargo testAfter tests finish and *-result.json files are present in your results directory,
use the Allure 3 CLI to generate and open the report:
allure generate ./target/allure-results --output ./target/allure-report --clean
allure open ./target/allure-reportIf you installed Allure 3 through Node tooling, use the equivalent
npxcommand provided by your installation method.
- Rust: stable toolchain (workspace uses Rust 2021 edition).
- OS: cross-platform by design (file-system based output, no OS-specific APIs).
- CI coverage in this repository currently runs on
ubuntu-latest.
Implemented runtime facade APIs include:
- Test lifecycle:
start_test_case,stop_test_case(plus compatibility aliasesstart_test,start_test_with_full_name,end_test) - Descriptions:
description,description_html - Labels:
label,labels,epic,feature,story,suite,parent_suite,sub_suite,owner,severity,layer,tag,tags,id - Links:
link,links,issue,tms - Parameters:
parameter - Attachments:
attachment - Steps:
step,log_step,#[step]with automatic stop viaStepGuard
use allure_cargotest::{allure_test, step};
#[allure_test]
#[test]
fn test_with_allure() {
allure.epic("Web interface");
allure.feature("Authentication");
allure.story("Login by user/password");
allure.parameter("browser", "firefox");
open_login_page();
}
#[step]
fn open_login_page() {
// your step implementation
}The #[allure_test] attribute initializes a reporter automatically (using
ALLURE_RESULTS_DIR or target/allure-results) and wraps the test lifecycle.
#[allure_test] also derives synthetic suite labels from the Rust module path when a full
name is available. A single module segment becomes suite; with two or more segments, the first
becomes parentSuite, the second becomes suite, and any remaining module segments are joined
into subSuite. If your test calls allure.parent_suite(...), allure.suite(...), or
allure.sub_suite(...), those explicit labels override the synthetic defaults for the same label
name.
allure-rust-commons is the foundation layer that other integrations build on.
It exports these main building blocks:
- Model (
model): Allure data structures (TestResult,StepResult, labels, links, parameters, attachments, statuses). - Lifecycle (
lifecycle):AllureRuntime: owns a results writer and creates per-execution lifecycles.AllureLifecycle: manages active test state, nested steps, metadata, and final write.
- Writer (
writer):FileSystemResultsWriter: writes result JSON and attachment files into an output directory.
- Facade (
facade):AllureFacade: ergonomic API for tests/framework adapters.- global
allure()accessor backed byOnceLock.
This separation lets you choose either:
- A high-level API (
AllureFacade) for minimal integration effort. - A low-level API (
AllureLifecycle+ model) for custom control.
To integrate Allure with another Rust test runner or framework:
- Initialize a writer and runtime once per process (or execution session).
- Create a lifecycle for test execution scope.
- Wrap framework hooks/events:
- on test start ->
start_test_case(...) - during test -> labels/links/parameters/steps/attachments
- on test end ->
stop_test_case(status, details)
- on test start ->
- Map framework statuses to Allure statuses (
Passed,Failed,Broken,Skipped). - Persist artifacts via
add_attachment(...)when your framework emits logs/files.
Minimal sketch:
use allure_rust_commons::{AllureRuntime, FileSystemResultsWriter, Status};
let writer = FileSystemResultsWriter::new("target/allure-results")?;
let runtime = AllureRuntime::new(writer);
let lifecycle = runtime.lifecycle();
lifecycle.start_test_case(
allure_rust_commons::StartTestCaseParams::new("my test").with_full_name("suite::my test")
);
// ... update metadata, steps, and attachments during execution ...
lifecycle.stop_test_case(Status::Passed, None);For convenience APIs, wrap the lifecycle in AllureFacade::with_lifecycle(...) and expose
framework-specific helpers similar to #[allure_test] from allure-cargotest.
Rust requires attribute procedural macros to be compiled from a proc-macro crate.
A proc-macro crate cannot serve as a regular runtime library crate at the same
time, so runtime/reporter APIs stay in allure-cargotest and macro implementation
lives in allure-test-macros.
From a user perspective this remains a single entrypoint because
allure-cargotest re-exports #[allure_test] and #[step].