Primeros pasos con Rust Cargo Test
Genera hermosos reportes HTML usando Allure Report y tus pruebas en Rust.
INFO
El crate principal orientado al usuario es allure-cargotest. Si estás construyendo tu propia integración para un runner o framework personalizado, usa allure-rust-commons en su lugar. El repositorio oficial allure-rust también publica Allure Reqwest (captura las llamadas HTTP de reqwest como adjuntos de intercambio HTTP de Allure) y Allure Diesel (registra las consultas Diesel ejecutadas como pasos de Allure).
Configuración
1. Prepara tu proyecto
Asegúrate de tener instalado un toolchain de Rust estable y reciente.
El workspace oficial de
allure-rustestá publicado para Rust 1.74 y versiones más recientes, y usa la edición Rust 2021.Abre una terminal y ve al directorio del proyecto. Por ejemplo:
bashcd /home/user/myprojectInstala Allure Report. El repositorio oficial de
allure-rustdocumenta el flujo de trabajo con la CLI de Allure 3.Agrega la integración
allure-cargotest:bashcargo add allure-cargotest --devAnota tus pruebas con
#[allure_test]. También puedes marcar funciones auxiliares con#[step]para que aparezcan como pasos separados en el reporte.rustuse allure_cargotest::{allure_test, step}; #[step] fn open_login_page() { // implementación de tu paso } #[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. Ejecutar pruebas
Ejecuta tus pruebas de la misma manera que de costumbre:
cargo testPor defecto, allure-cargotest escribe los resultados en target/allure-results.
Para usar un directorio diferente, establece ALLURE_RESULTS_DIR antes de la ejecución de prueba:
ALLURE_RESULTS_DIR=./allure-results cargo testSi el directorio de resultados ya existe, los nuevos archivos se agregan a los existentes, de modo que un futuro reporte se basará en todos ellos.
3. Generar un reporte
Después de la ejecución de prueba, genera y abre el reporte con la CLI de Allure:
allure generate ./target/allure-results --output ./target/allure-report --clean
allure open ./target/allure-reportSi cambiaste el directorio de resultados con ALLURE_RESULTS_DIR, usa esa ruta en el comando allure generate.
Escribir pruebas
Rust Cargo Test extiende la salida estándar de cargo test con características de reporte más detalladas. Puedes usarlo para:
- agregar descripciones, propietarios, enlaces y otros metadatos,
- organizar las pruebas en jerarquías basadas en comportamiento y en suites,
- dividir la ejecución en pasos anidados,
- describir parámetros y adjuntos,
- escribir pruebas asíncronas con Tokio,
- ejecutar solo las pruebas seleccionadas mediante un archivo de plan de pruebas.
Agregar metadatos
Dentro de una función marcada con #[allure_test], la macro inyecta una fachada allure que puedes usar para enriquecer el resultado de prueba:
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");
}Un comentario de documentación de Rust en la función de prueba se usa como la descripción markdown predeterminada, por lo que a menudo no necesitas llamar a allure.description(...) en absoluto:
use allure_cargotest::allure_test;
/// Verifies login with a username and a password.
#[allure_test]
#[test]
fn login_works() {
// ...
}Llamar a allure.description(...) en el cuerpo de la prueba sobrescribe la descripción del comentario de documentación para esa ejecución, y allure.description_html(...) establece una descripción HTML explícita. Usa #[allure_test(doc = false)] para deshabilitar la descripción del comentario de documentación para una sola prueba.
Organizar pruebas
Allure admite jerarquías tanto basadas en comportamiento como en suites. Por 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");
}Cuando usas #[allure_test], allure-cargotest también deriva automáticamente etiquetas de suite a partir de la ruta del módulo de Rust. Las llamadas explícitas a allure.parent_suite(...), allure.suite(...) o allure.sub_suite(...) sobrescriben las etiquetas sintéticas con el mismo nombre.
Dividir una prueba en pasos
Puedes declarar funciones de paso reutilizables con #[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();
}También puedes crear pasos directamente desde la API de runtime. allure.step(name, || { ... }) envuelve un closure como un paso y devuelve su valor; allure.enter_step(name) devuelve un guard que mantiene el paso abierto hasta que se elimina, lo cual es útil cuando el paso abarca código que no es un único closure:
use allure_cargotest::allure_test;
#[allure_test]
#[test]
fn login_works() {
allure.step("Open login page", || {
// ...
});
let _guard = allure.enter_step("Check profile page");
// ...
}Agregar parámetros y adjuntos
Los parámetros y adjuntos se almacenan en los resultados de Allure generados y se muestran en el reporte:
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}"#,
);
}Ejecutar pruebas asíncronas con Tokio
Combina #[allure_test] con una macro de prueba específica del runtime, como #[tokio::test]. Agrega y configura Tokio en tu propio crate de pruebas; allure-cargotest en sí no depende de Tokio.
use allure_cargotest::allure_test;
#[allure_test]
#[tokio::test]
async fn login_works_async() {
allure.feature("Authentication");
tokio::task::yield_now().await;
allure.parameter("runtime", "tokio");
}El contexto de Allure está disponible en el cuerpo raíz de la prueba asíncrona y en los ayudantes esperados (awaited). Las tareas de Tokio generadas independientemente no heredan implícitamente el contexto actual de Allure.
Tanto las pruebas síncronas como asíncronas también pueden devolver Result<(), E>, ExitCode, u otro tipo que implemente std::process::Termination, en lugar de (). Los valores Err devueltos y los valores de terminación no exitosos se reportan a Allure antes de que Cargo interprete el resultado:
use allure_cargotest::allure_test;
#[allure_test]
#[test]
fn login_works() -> Result<(), String> {
allure.feature("Authentication");
if !login("demo") {
return Err("login failed".to_string());
}
Ok(())
}Seleccionar pruebas mediante un archivo de plan de pruebas
allure-cargotest admite el mecanismo estándar de plan de pruebas de Allure mediante la variable de entorno ALLURE_TESTPLAN_PATH.
Crea un archivo JSON como el siguiente:
{
"version": "1.0",
"tests": [{ "selector": "auth::tests::login_works" }]
}Luego ejecuta las pruebas con:
ALLURE_TESTPLAN_PATH=./testplan.json cargo testLas entradas con selector coinciden con el nombre completo de la prueba en Rust, incluida su ruta de módulo, y funcionan con #[allure_test].
WARNING
Las entradas con id se comparan con un ID explícito de Allure (o un tag @allure.id=... / @allure.id:...) que el llamador pasa explícitamente a la búsqueda del plan de pruebas. #[allure_test(id = "...")] actualmente no reenvía su id a esa búsqueda, por lo que las entradas id no tienen efecto en las pruebas escritas con la macro; usa entradas selector para ellas en su lugar. Las integraciones que llaman directamente a CargoTestReporter::run_test_with_metadata pueden pasar un allure_id, y las entradas id sí coinciden ahí. Consulta la Referencia para CargoTestReporter.
Construir una integración personalizada
Si necesitas integrar Allure con un runner o framework de pruebas personalizado en Rust, usa allure-rust-commons:
cargo add allure-rust-commonsEn ese nivel, creas un writer, inicializas un runtime, inicias un caso de prueba y lo detienes cuando la ejecución termina:
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"),
);
// ... actualiza metadatos, agrega pasos y adjuntos ...
lifecycle.stop_test_case(Status::Passed, None);
Ok(())
}Consulta la Referencia para los principales macros y APIs de runtime, o la Configuración para las variables de entorno admitidas.