Description
Imagine a (contrived) piece of code like this:
lazy_static!(Q: Mutex<Vec<u32>> = Mutex::new(Vec::new()));
#[test]
fn test_a() {
{
Q.lock().unwrap().push(5);
}
assert_eq!(Q.lock().unwrap().len(), 1);
}
fn test_b() {
{
Q.lock().unwrap().clear();
}
assert_eq!(Q.lock().unwrap().len(), 0);
{
let q = Q.lock().unwrap();
q.push(5);
q.push(6);
}
assert_eq!(Q.lock().unwrap().len(), 2);
}
This is broken by default because cargo test will by default spawn multiple threads for the tests so the global state of Q. The user would have to know to pass --test-threads=1 or the test author would have to create a global mutex to synchronize each test on. This seems like a lot of unnecessary boilerplate, not to mention an unnecessary pain point for new developers to discover when they can't figure out why tests are producing weird results.
There also doesn't seem to be a solution at the moment that would enable you to achieve the benefits of running tests in parallel at all for shared state between tests. The global mutex approach effectively reduces the test code to implicitly running with --test-threads=1. Using separate processes by default (or at least providing a decorator to do it easily) would solve the vast majority of such problems without requiring authors to significantly restructure their code.
FWIW, other test frameworks go with the process sharding approach instead of threads.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status