Referencia de Rust Cargo Test
Estos son los principales bloques de construcción que puedes usar para integrar pruebas de Rust con Allure mediante allure-cargotest.
Macros
#[allure_test]
Formas compatibles:
#[allure_test]#[allure_test(name = "Login works")]#[allure_test(id = "AUTH-1")]#[allure_test(doc = false)]#[allure_test(name = "Login works", id = "AUTH-1")]
Usa el macro junto con #[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");
}Lo que hace el macro:
- inicializa el reporter usando
ALLURE_RESULTS_DIRotarget/allure-results, - inyecta una fachada
allureen el cuerpo de la prueba, - inicia y detiene el ciclo de vida de la prueba automáticamente,
- aplica las etiquetas predeterminadas descritas en Configuración,
- deriva etiquetas de suite a partir de
module_path!(), - usa el comentario de documentación de Rust de la función como descripción markdown predeterminada, a menos que se establezca
doc = falseo se llame adescription(...)en el cuerpo de la prueba.
Notas de comportamiento:
#[allure_test]admite tanto funciones síncronas comoasync fn; combínalo con un macro de prueba específico del runtime, como#[tokio::test], colocado debajo de él (allure-cargotestno depende de Tokio en sí),- además de
(), las funciones de prueba pueden devolverResult<T, E>(dondeTes a su vez un tipo de retorno compatible),ExitCode, o cualquier otro tipo que implementestd::process::Termination; los valoresErry los valores de terminación no exitosos se reportan a Allure antes de que Cargo interprete el resultado, #[should_panic]está soportado solo para pruebas que devuelven(),#[should_panic(expected = "...")]marca la prueba como aprobada solo cuando el mensaje de pánico contiene la subcadena esperada,- un pánico dentro del cuerpo de la prueba siempre se reporta como
failed, sin importar su mensaje —brokensolo se produce por unResult::Errdevuelto, unExitCodeno exitoso, o un valorTerminationpersonalizado no exitoso (ver el punto sobre el tipo de retorno arriba), nunca por un pánico.
#[step]
Formas compatibles:
#[step]#[step(name = "Open login page")]
Usa #[step] en funciones auxiliares que quieras mostrar como pasos en el reporte:
use allure_cargotest::{allure_test, step};
#[step(name = "Open login page")]
fn open_login_page() {
// ...
}
#[allure_test]
#[test]
fn login_works() {
open_login_page();
}Cuando la función se ejecuta dentro de una prueba Allure activa, la integración inicia y detiene un paso automáticamente. Fuera de un contexto Allure activo, la función se comporta como una función Rust normal.
API de la fachada en tiempo de ejecución
Dentro de #[allure_test], la fachada allure proporciona métodos para las tareas de reporte más comunes.
Metadatos y etiquetas
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)
Ejemplo:
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"]);
}Identidad y visualización
allure.display_name(name)— anula el nombre mostrado en el reporte, independientemente de#[allure_test(name = "...")], para los casos en los que el nombre para mostrar debe calcularse en tiempo de ejecuciónallure.history_id(value)— anula el identificador que Allure usa para asociar este resultado con ejecuciones anteriores para el seguimiento de reintentos/inestabilidad/historial (por defecto se deriva del nombre completo de la prueba y de los parámetros no excluidos)allure.test_case_id(value)— anula el identificador que Allure usa para agrupar resultados en un caso de prueba lógico único entre entornos (por defecto se deriva del nombre completo de la prueba)
Ejemplo:
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");
}Jerarquías
allure.epic(value)allure.feature(value)allure.story(value)allure.parent_suite(value)allure.suite(value)allure.sub_suite(value)
Ejemplo:
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");
}Enlaces y parámetros
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: truemantiene el parámetro visible en el reporte sin permitir que afecte a la identidad de historial/reintento calculada a partir de los parámetrosallure.parameter_mode(name, value, mode)— unParameterModedeallure_rust_commons:Maskedmuestra el nombre pero oculta el valor (para secretos),Hiddenelimina el parámetro del reporte por completo,Defaultes la visualización normalallure.parameter_with_options(name, value, excluded, mode)— combina ambos controles en una sola llamada
Ejemplo:
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);
}Adjuntos
allure.attachment(name, content_type, body)allure.attachment_path(name, content_type, path)— lee el cuerpo del adjunto desde un archivoallure.attach_trace(path)/allure.attach_trace_named(name, path)— adjunta un archivo de traza de Playwright existente (un envoltorio de conveniencia alrededor deattachment_pathque usa el tipo de contenidoapplication/vnd.allure.playwright-trace, de modo que el visor de trazas de Allure lo abra en lugar de ofrecer una descarga de zip simple;attach_traceusatrace.zipcomo nombre de adjunto predeterminado) — no genera trazas ni depende de Playwright en sí
Ejemplo:
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");
}Diagnósticos a nivel de ejecución (globales)
Estos adjuntan evidencia a toda la ejecución de prueba (el nivel de lanzamiento/Entorno del reporte) en lugar de a la prueba actual. Pueden llamarse desde dentro de #[allure_test], o de forma independiente incluso cuando no hay ninguna prueba activa actualmente:
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)
Ejemplo:
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");
}Pasos
allure.step(name, || { ... })ejecuta una closure como un paso y devuelve su valorallure.enter_step(name)devuelve unStepGuardque mantiene el paso abierto hasta que se descartaallure.log_step(name)allure.log_step_with(name, status, error)
Ejemplos:
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 también te permite sobrescribir el estado final del paso antes de que el guard sea descartado, con fail o el más general set_status:
use allure_cargotest::allure_test;
#[allure_test]
#[test]
fn login_works() {
let mut guard = allure.enter_step("Validate response");
guard.fail("Unexpected status code");
}Etapas
allure.stage(name)abre un nuevo paso "de etapa" con nombre. A diferencia destep/enter_step, no cierras una etapa explícitamente — iniciar la siguiente etapa (o finalizar la prueba) cierra automáticamente la anterior como aprobada. Todo lo que se registre entre medio (pasos, adjuntos, aserciones registradas) se anida bajo la etapa que esté actualmente abierta.
Ejemplo:
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>");
}Esto produce dos pasos de nivel superior — open login page (que contiene login page opened) y collect evidence (que contiene el adjunto page.html) — sin anidar closures manualmente.
Integración manual con CargoTestReporter
Si los macros no son suficientes para tu harness de pruebas, puedes usar CargoTestReporter directamente:
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(())
}Métodos útiles:
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 e is_selected son los únicos puntos de entrada que reenvían un par explícito de allure_id/tags a la coincidencia del plan de pruebas, por lo que las entradas id en un archivo ALLURE_TESTPLAN_PATH solo tienen efecto para integraciones construidas directamente sobre CargoTestReporter — no para #[allure_test(id = "...")], que actualmente solo participa en la coincidencia de selector.
Construyendo una integración personalizada con allure-rust-commons
Usa allure-rust-commons cuando necesites control de bajo nivel sobre el ciclo de vida:
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(())
}Los principales tipos de bajo nivel son:
AllureRuntimeAllureLifecycleStartTestCaseParamsFileSystemResultsWriterStatusyStatusDetails- los tipos del modelo exportados desde
allure_rust_commons::model