liveBook · Manning

Libtest

As explained in Code Like a Pro in Rust

libtest is Rust's built-in test harness library for discovering, executing, and reporting test results.

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

How Code Like a Pro in Rust covers it

How deep it goes
Explains parallel-execution pitfalls and fixture alternatives, but does not detail libtest’s implementation.
Examples
Contrasts a rejected mutable-static counter with atomic counters and a mutex shared by two tests.
What it assumes
Assumes familiarity with Rust unit tests and introduces lazy_static for runtime-initialized shared fixtures.
What you can do after
Operate/configure it by retaining parallel tests while synchronizing shared fixtures, or disabling the built-in harness for a custom main.
How it connects
Connects unit testing to threads, mutable statics, atomic integers, mutexes, and lazy_static.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Code Like a Pro in Rust. The section links point to the parts of the book it draws on.