White-box testing verifies code with access to its internals. In Rust, tests placed alongside an implementation can inspect private structs, fields, and functions, making the technique useful for checking a procedural macro’s intermediate behavior rather than only its externally visible result. section 6.3 section 6.9
Start with a small assertion over a helper’s output, then strengthen it only where precision matters. Generated token streams can be checked by searching their string form, comparing them with an expected stream produced by `quote!`, or parsing output with `syn::parse2` and asserting on the resulting syntax tree. section 6.3
Testing generated builder output
Pass `struct StructWithNoFields {}` to `create_builder`, then assert that the output contains `StructWithNoFieldsBuilder`. A stricter test compares the generated stream against `quote! { struct StructWithNoFieldsBuilder {} }`; a structural alternative parses the output and checks the derived identifier. section 6.3
Use white-box tests deliberately:
- Test private pure functions and transformations directly, where controlled inputs and outputs make coverage straightforward. section 6.5
- Use them to isolate tricky macro errors or verify behavior that matters independently of an end-to-end compilation check. section 6.9
- Avoid asserting incidental output layout: small internal changes can break a white-box test without changing meaning. section 6.5 section 6.4
- Pair them with black-box compilation tests, which validate required behavior from the outside and are generally less brittle. section 6.5 section 6.9
Listing 6.5 Our builder-code with a first, basic test
// imports
pub fn create_builder(item: TokenStream) -> TokenStream {
let ast: DeriveInput = syn::parse2(item).unwrap();
let name = ast.ident;
let builder = format_ident!("{}Builder", name); #1
quote! {
struct #builder {}
}
}
#[cfg(test)]
mod tests { #2
use super::*;
#[test]
fn builder_struct_name_should_be_present_in_output() {
let input = quote! { #3
struct StructWithNoFields {}
};
let actual = create_builder(input);
assert!(actual.to_string()
.contains("StructWithNoFieldsBuilder")); #4
}
}
A minimal Rust unit test demonstrates colocating a test with macro implementation code, constructing input with `quote!`, invoking the helper, and checking generated output. section 6.3


