I'm dealing with a lot of tests that all have the same structure as follows:
#[cfg(test)]
mod tests {
#[test]
fn test_sample() {
// create file, optionally write something inside
File::create(<FILE_NAME>).unwrap();
// test stuff with file
// delete file
fs::remove_file(<FILE_NAME>).unwrap();
}
}
My main concern is the sheer amount of duplicate code across all tests. I've tried using crates for creating a single global temp directory with the INIT.call_once() pattern shown here, but it doesn't work because I can't declare a static or const variable at the module level without also initializing it. Obviously it would work if I created a separate temp directory in each test, but I'd like to create only one and then inject it inside the tests like rstest does with fixtures.
Is it possible to achieve this kind of behaviour with temp directories? If not, I'd like to try the same thing with temp files, i.e. injecting them as fixtures. It should work, but I wanted to ask just in case. Or perhaps do you have other ideas for approaching this issue?
I've done something similar but with more files to be created, although it could get kinda messy but it's the best solution in my case.
It's basically using a wrapper function so that the test functions can get the path to the files/dirs created before running the actural tests:
//tests/common.rs
pub fn run<T>(test: T, clean_after: bool)
where
T: FnOnce(&TestPaths) -> () + panic::UnwindSafe,
{
let paths = init().unwrap();
let res = panic::catch_unwind(|| {
test(&paths);
});
if clean_after {
clean(&paths).unwrap();
}
assert!(res.is_ok());
}
and in each test functions:
#[test]
fn tast1() {
run(
|paths| {
// package metadata
let p = paths.root.join("test1.toml");
...
},
false,
);
}
And you'll have to write your own init() function to return the what ever paths created, and clear(&paths) to clears them ofc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With