I have a crate with production code in the src
directory and integration tests in the tests
directory. The production code uses log
ma
In addition to Danilo Bargen's comment, you can write it in a shorter form:
use std::sync::Once;
static INIT: Once = Once::new();
fn setup() {
INIT.call_once(env_logger::init);
}
There's no good way to do this kind of thing built-in right now.
You can write a macro that inserts some sort of initialization call before each test, but that's as close as there is.
You can use something like this:
use std::sync::Once;
static INIT: Once = Once::new();
/// Setup function that is only run once, even if called multiple times.
fn setup() {
INIT.call_once(|| {
env_logger::init().unwrap();
});
}
Then simply call setup()
in the beginning of each test.
Originally based on this blogpost.
For now, you can just re-initialize the logger at the top of every test and ignore the error. It's not a pretty solution but it works and is perfectly safe.
let _ = env_logger::init();
// your test code...
I've observed cargo test
running the tests in alphabetical order, so I devised a very dirty hack to initialize the logger.
aaa_testing
residing inside the root of the crate.Inside the module, I wrote the logger initializer.
#[test]
fn initialize_logger() {
env_logger::init();
}
Yes I did create a test that will always pass, but if you want to have a test for initializing the logger, you can do a assert!(env_logger::try_init().is_ok());
Shepmaster pointed out that cargo test
runs tests asynchronously and may make logging of the first few tests unreliable. To prevent this, the tests can be ran in the same thread. (This will cause performance problems, so this answer should not be used if you need multiple threads to test your project.)
If you want to control the number of simultaneous running test cases, pass the
--test-threads
option to the test binaries:cargo test -- --test-threads=1
The latest documentation has a recommendation:
#[cfg(test)]
mod tests {
fn init() {
let _ = env_logger::builder().is_test(true).try_init();
}
#[test]
fn it_works() {
init();
info!("This record will be captured by `cargo test`");
assert_eq!(3, 1 + 2);
}
}