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]:
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_DIRortarget/allure-results, - injects an
allurefacade into the test body, - starts and stops the test lifecycle automatically,
- applies the default labels described in Configuration,
- derives suite labels from
module_path!().
Behavior notes:
#[allure_test]currently supports only synchronous test functions that return(),async fnis 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:
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 adapter 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:
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:
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:
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:
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)returnsStepGuardallure.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:
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:
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:
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 adapter with allure-rust-commons
Use allure-rust-commons when you need low-level control over the lifecycle:
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:
AllureRuntimeAllureLifecycleStartTestCaseParamsFileSystemResultsWriterStatusandStatusDetails- the model types exported from
allure_rust_commons::model