Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Pattern 20: Macro Pattern Enforcement

Context

You need consistent test structure and timeouts without repeating boilerplate or relying on discipline alone.

Problem

Developers forget to add timeouts, skip AAA comments, or mix direct #[test] usage with framework macros, leading to drift and inconsistent behavior.

Solution

Embed enforcement inside macros. test! injects the AAA skeleton, async_test! and fixture_test! wrap bodies with tokio::time::timeout, and weaver_test! requires the weaver feature. Each macro centralizes best practices so using it guarantees compliance.

Forces

  • Consistency vs. flexibility: macros enforce conventions while allowing custom logic inside
  • Zero cost vs. tooling: expansions must stay small and compile quickly
  • Guidance vs. noise: failures should point to the missing convention explicitly

Examples

#![allow(unused)]
fn main() {
#[macro_export]
macro_rules! async_test {
    ($name:ident, $body:block) => {
        $crate::async_test_with_timeout!($name, 1, $body);
    };
}
}
#![allow(unused)]
fn main() {
#[cfg(not(feature = "otel"))]
#[macro_export]
macro_rules! otel_test {
    ($($tt:tt)*) => {
        compile_error!("OTEL testing requires the 'otel' feature. Enable with: --features otel");
    };
}
}
  • Pattern 1: AAA Pattern
  • Pattern 18: Timeout Defense in Depth
  • Pattern 19: Feature Gate Slices