I wish to simulate the user being present in another directory in my test cases. I have a couple cases in the project root.
| examples/
| | test1_dir/
| | test2_dir/
| src/
| |- main.rs
| |- lib.rs
| |- config.rs
|- Cargo.toml
|- Cargo.lock
Inside config.rs
, there are two test cases that look like the following:
#[test]
fn config_find_file() {
let original_dir = env::current_dir().unwrap();
env::set_current_dir("examples/test1_dir").unwrap();
// ...
env::set_current_dir(original_dir);
}
#[test]
fn config_find_file_2() {
let original_dir = env::current_dir().unwrap();
env::set_current_dir("examples/test2_dir").unwrap();
// ...
env::set_current_dir(original_dir);
}
When I execute with simply cargo test
, it fails 50% of the time. This is because sometimes Rust enters a race condition and tries to locate examples/test1_dir/examples/test2_dir
. To make it pass, I have to run cargo test -- --test-threads=1
. However, I have multiple tests in this project and I don't wish to run one thread for all of them. Here are a few things I have tried:
cargo test --lib config -- --test-threads=1
. But there is no way that I can execute all other tests but the config tests, resulting in a plethora of test commands for every lib I define.How should I approach this issue?
There is a crate called serial_test that provides the proc macro #[serial]
.
Any test you use this macro on will run single threaded, with all other tests running in parallel (as is the default for cargo).
For example, consider these 4 tests. The parallel tests will run in parallel, and the serial tests will wait for other tests to finish then run only one at a time.
#[test]
fn test_parallel_one() {}
#[test]
fn test_parallel_two() {}
#[test]
#[serial]
fn test_serial_one() {}
#[test]
#[serial]
fn test_serial_another() {}