141 Followers
·
Follow

Test setup and teardown in Rust without a framework.

When I read the announcement about being able to handle panics using catch_unwind (https://doc.rust-lang.org/std/panic/fn.catch_unwind.html) I thought I would never have a reason to use it. But…

I’m testing some code that requires a fair amount of setup and teardown and I wanted to DRY it up. The problem was that the teardown step in the original code had to run before the test assertion otherwise the teardown code wouldn’t run if a test failed. asserts panic and nothing after the assert will run.

The original code looked something like:

#[test]
fn test_something_interesting() {
setup();

let true_or_false = do_the_test();

teardown();

assert!(true_or_false);
}

The refactored code looked like:

#[test]
fn test_something_interesting() {
run_test(|| {
let true_or_false = do_the_test();

assert!(true_or_false);
})
}

fn run_test<T>(test: T) -> ()
where T: FnOnce() -> ()
{
setup();

test();

teardown();
}

which doesn’t work because if the assert fails teardown() will never run.

Then I started to write a macro which I won’t even post here because your eyes will bleed and I never got it to work and I hated it and I dislike macros in general.

After a little googling and realizing I needed a way to catch a panic…

Oh, yah. The announcement.

A little experimentation and I wound up with:

#[test]
fn test_something_interesting() {
run_test(|| {
let true_or_false = do_the_test();

assert!(true_or_false);
})
}
fn run_test<T>(test: T) -> ()
where T: FnOnce() -> () + panic::UnwindSafe
{
setup();

let result = panic::catch_unwind(|| {
test()
});

teardown();

assert!(result.is_ok())
}

The coolest thing about this solution is that it produces the same errors the assert panic would produce in the original code.

I tried to find code or a blog or some other documentation where this is being done. I didn’t find anything. So it’s either really bad or no one is talking about it for some reason. Please let me know if there’s something wrong with doing this.

Written by

I talk to computers. My aura is a series of 1’s and 0’s. I’m a technologist. I’m a renaissance man. I’m Mr. Average trying to do things that are hard.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store