转载:Test setup and teardown in Rust without a framework

193 阅读1分钟

原文连接:Test setup and teardown in Rust without a framework. | by Eric Opines | Medium

When I read the announcement about being able to handle panics using catch_unwind (doc.rust-lang.org/std/panic/f…) 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.