#[mae_test]Expand description
#[mae_test] — the standard macro for async journey tests in Mae services.
§What it does
Wraps an async fn test in a dedicated multi-threaded Tokio runtime, enforces the
Mae test-hygiene rules (no raw .unwrap() / .expect() / assert*! in test bodies),
and optionally:
- gates the test on
MAE_TESTCONTAINERS=1at compile time (dockerflag) - runs an async teardown function after the test body (
teardown = pathargument)
§Attributes
| Argument | Effect |
|---|---|
| (none) | Basic multi-threaded async test |
docker | Skips test unless compiled with MAE_TESTCONTAINERS=1 |
teardown = crate::common::context::teardown | Calls given async fn after test, even on panic |
§Examples
ⓘ
use mae_macros::mae_test;
// Good: returns Result, uses `?` and `must::*` helpers
#[mae_test]
async fn journey_create_user() -> Result<(), anyhow::Error> {
let ctx = TestContext::new().await?;
let user = ctx.create_user("alice").await?;
must_eq(user.name, "alice");
Ok(())
}
// Docker-gated: only runs when MAE_TESTCONTAINERS=1 cargo test
#[mae_test(docker)]
async fn journey_with_postgres() -> Result<(), anyhow::Error> {
let ctx = TestContext::new().await?;
// ... test using real DB
Ok(())
}
// With explicit teardown
#[mae_test(teardown = crate::common::context::teardown)]
async fn journey_with_cleanup() -> Result<(), anyhow::Error> {
let ctx = TestContext::setup().await?;
ctx.do_work().await?;
Ok(())
}
// Bad: uses raw .unwrap() — compile error
#[mae_test]
async fn bad_test() {
let x: Option<i32> = None;
let _ = x.unwrap(); // ❌ compile error: forbidden
}