libtest is Rust’s built-in test harness. Cargo runs unit tests on multiple threads, usually without special handling. Parallel execution speeds up ordinary tests but matters when tests share state or depend on timing. section 6.5 section 6.10
Do not use an unprotected mutable static as a shared test counter: the compiler rejects access because concurrent mutation can cause data races. Use an atomic value for a counter, or a mutex when tests must coordinate access to shared state. If a fixture needs runtime initialization, lazy_static can create it on first access; it does not replace the synchronization the fixture requires. section 6.5
#[cfg(test)]
mod tests {
use lazy_static::lazy_static;
use std::sync::Mutex;
lazy_static! {
static ref MUTEX: Mutex<i32> = Mutex::new(0);
}
#[test]
fn first_test() {
let _guard = MUTEX.lock().expect("couldn’t acquire lock");
println!("first test is running");
}
#[test]
fn second_test() {
let _guard = MUTEX.lock().expect("couldn’t acquire lock");
println!("second test is running");
}
}
Two tests acquire the same mutex and hold its guard while running. They can still be scheduled in parallel, but their protected work cannot overlap. section 6.5
Replacing libtest with a custom test main is possible by setting `harness = false` in the target settings, but is generally more trouble than using a shared fixture. section 6.5
