Getting started with Rust Cargo Test
Generate beautiful HTML reports using Allure Report and your Rust tests.
INFO
The main user-facing crate is allure-cargotest. If you are building your own adapter for a custom runner or framework, use allure-rust-commons instead. Both crates live in the official allure-rust repository.
Setting up
1. Prepare your project
Make sure a recent stable Rust toolchain is installed.
The official
allure-rustworkspace is published for Rust 1.74 and newer and uses the Rust 2021 edition.Open a terminal and go to the project directory. For example:
bashcd /home/user/myprojectInstall Allure Report. The official
allure-rustrepository documents the workflow with the Allure 3 CLI.Add the
allure-cargotestadapter:bashcargo add allure-cargotest --devAnnotate your tests with
#[allure_test]. You can also mark helper functions with#[step]so they appear as separate steps in the report.rustuse allure_cargotest::{allure_test, step}; #[step] fn open_login_page() { // your step implementation } #[allure_test] #[test] fn login_works() { allure.epic("Web interface"); allure.feature("Authentication"); allure.story("Login with username and password"); allure.parameter("browser", "firefox"); open_login_page(); allure.attachment("page.html", "text/html", "<html>...</html>"); }
2. Run tests
Run your tests the same way as usual:
cargo testBy default, allure-cargotest writes the results to target/allure-results.
To use a different directory, set ALLURE_RESULTS_DIR before the test run:
ALLURE_RESULTS_DIR=./allure-results cargo testIf the results directory already exists, the new files are added to the existing ones, so that a future report will be based on all of them.
3. Generate a report
After the test run, generate and open the report with the Allure CLI:
allure generate ./target/allure-results --output ./target/allure-report --clean
allure open ./target/allure-reportIf you changed the results directory with ALLURE_RESULTS_DIR, use that path in the allure generate command.
Writing tests
Rust Cargo Test extends plain cargo test output with richer reporting features. You can use it to:
- add descriptions, owners, links, and other metadata,
- organize tests into behavior-based and suite-based hierarchies,
- split the execution into nested steps,
- describe parameters and attachments,
- run only selected tests through a test plan file.
Add metadata
Inside a function marked with #[allure_test], the macro injects an allure facade that you can use to enrich the test result:
use allure_cargotest::allure_test;
#[allure_test(name = "Login works", id = "AUTH-1")]
#[test]
fn login_works() {
allure.description("This test verifies login with a username and a password.");
allure.owner("John Doe");
allure.tag("smoke");
allure.severity("critical");
allure.issue("AUTH-123", "https://jira.example.com/browse/AUTH-123");
allure.tms("TMS-456", "https://tms.example.com/cases/TMS-456");
}Organize tests
Allure supports both behavior-based and suite-based hierarchies. For example:
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");
}When you use #[allure_test], allure-cargotest also derives suite labels from the Rust module path automatically. Explicit calls to allure.parent_suite(...), allure.suite(...), or allure.sub_suite(...) override the synthetic labels with the same name.
Divide a test into steps
You can declare reusable step functions with #[step]:
use allure_cargotest::{allure_test, step};
#[step(name = "Open login page")]
fn open_login_page() {
// ...
}
#[step(name = "Submit credentials")]
fn submit_credentials() {
// ...
}
#[allure_test]
#[test]
fn login_works() {
open_login_page();
submit_credentials();
}You can also create steps directly from the runtime API:
use allure_cargotest::allure_test;
#[allure_test]
#[test]
fn login_works() {
allure.step_with("Open login page", || {
// ...
});
let _guard = allure.step("Check profile page");
// ...
}Add parameters and attachments
Parameters and attachments are stored in the generated Allure results and rendered in the report:
use allure_cargotest::allure_test;
#[allure_test]
#[test]
fn login_works() {
allure.parameter("browser", "firefox");
allure.parameter("environment", "staging");
allure.attachment(
"request.json",
"application/json",
br#"{"username":"demo","rememberMe":true}"#,
);
}Select tests via a test plan file
allure-cargotest supports the standard Allure test plan mechanism via the ALLURE_TESTPLAN_PATH environment variable.
Create a JSON file such as:
{
"version": "1.0",
"tests": [{ "id": "AUTH-1" }, { "selector": "auth::tests::login_works" }]
}Then run the tests with:
ALLURE_TESTPLAN_PATH=./testplan.json cargo testEntries with id match tests annotated with #[allure_test(id = "...")]. Entries with selector match the full Rust test name, including its module path.
Building a custom integration
If you need to integrate Allure with a custom Rust test runner or framework, use allure-rust-commons:
cargo add allure-rust-commonsAt that level, you create a writer, initialize a runtime, start a test case, and stop it when execution ends:
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"),
);
// ... update metadata, add steps, and add attachments ...
lifecycle.stop_test_case(Status::Passed, None);
Ok(())
}See Reference for the main macros and runtime APIs, or Configuration for the supported environment variables.