---
title: Rust Cargo Test reference
description: Reference documentation for the allure-cargotest integration | Macros | Metadata | Steps | Attachments | Manual integration
---

# 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(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](/docs/rust-configuration/),
- derives suite labels from `module_path!()`.

Behavior notes:

- `#[allure_test]` currently supports only synchronous test functions that return `()`,
- `async fn` is not supported,
- `#[should_panic]` is supported,
- `#[should_panic(expected = "...")]` marks the test as passed only when the panic message contains the expected substring.

### `#[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"]);
}
```

### 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)`

Example:

```rust
use allure_cargotest::allure_test;

#[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");
}
```

### Attachments

- `allure.attachment(name, content_type, body)`

Example:

```rust
use allure_cargotest::allure_test;

#[allure_test]
#[test]
fn login_works() {
    allure.attachment(
        "response.json",
        "application/json",
        br#"{"status":"ok","user":"demo"}"#,
    );
}
```

### Steps

- `allure.step(name)` returns `StepGuard`
- `allure.step_with(name, || { ... })`
- `allure.log_step(name)`
- `allure.log_step_with(name, status, error)`
- `allure.step_display_name(name)`
- `allure.step_parameter(name, value)`

Examples:

```rust
use allure_cargotest::{allure_test, Status};

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

    let _guard = allure.step("Submit credentials");
    // ...

    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:

```rust
use allure_cargotest::allure_test;

#[allure_test]
#[test]
fn login_works() {
    let _guard = allure.step("Validate response").failed("Unexpected status code");
}
```

## 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(full_name, allure_id, tags)`

## 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`
