29

In Rust, is there any way to execute a teardown function after all tests have been run (i.e. at the end of cargo test) using the standard testing library?

I'm not looking to run a teardown function after each test, as they've been discussed in these related posts:

These discuss ideas to run:

One workaround is a shell script that wraps around the cargo test call, but I'm still curious if the above is possible.

kmdreko
  • 42,554
  • 6
  • 57
  • 106
Ivan Gozali
  • 2,089
  • 1
  • 27
  • 25
  • I tried that but couldn't get it to work. Something like [this](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=8224db31fdf2f2ef099e313d937bfcde), maybe? – Ivan Gozali Nov 27 '19 at 22:54
  • you can make a script I think like `build.rs`, you must probably configure a profil – Stargateur Nov 27 '19 at 23:03
  • 2
    You are right, destructors aren't run for static variables – see https://stackoverflow.com/questions/48732387/how-can-i-run-clean-up-code-in-a-rust-library as well. – Sven Marnach Nov 28 '19 at 08:35
  • 6
    There's an accepted experimental RFC to allow custom test frameworks – see [this tracking issue](https://github.com/rust-lang/rust/issues/50297). This would allow a lot more flexibility around tests, but unfortunately there hasn't been much progress on this yet. – Sven Marnach Nov 28 '19 at 09:38
  • As @SvenMarnach, I think that there is no solution to this issue unless this RFC is implemented. If you use the nightly compiler, you can do that with the few that was implemented AFAIK – Boiethios Nov 28 '19 at 09:56
  • People often use trybuild (https://docs.rs/trybuild/1.0.18/trybuild/) for testing procedural macros, and I'm fairly certain you can actually apply this crate to any use case, even custom testing framework, if you must. Maybe if someone built such thing on top of this, the RFC mentioned above might even move forward? –  Nov 28 '19 at 09:57

2 Answers2

3

I'm not sure there's a way to have a global ("session") teardown with Rust's built-in testing features, previous inquiries seem to have yielded little, aside from "maybe a build script". Third-party testing systems (e.g. shiny or stainless) might have that option though, might be worth looking into their exact capabilities

Alternatively, if nightly is suitable there's a custom test frameworks feature being implemented, which you might be able to use for that purpose.

That aside, you may want to look at macro_rules! to cleanup some boilerplate, that's what folks like burntsushi do e.g. in the regex package.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Masklinn
  • 34,759
  • 3
  • 38
  • 57
2

Here is an example implementation of the custom test framework solution mentioned by Masklinn:

#![feature(custom_test_frameworks)]
#![feature(test)]
#![test_runner(custom_test_runner)]

extern crate test;

use test::{test_main_static, TestDescAndFn};

fn main() {}

pub fn custom_test_runner(tests: &[&TestDescAndFn]) {
    println!("Setup");
    test_main_static(tests);
    println!("Teardown");
}

#[cfg(test)]
mod tests {

    #[test]
    fn test1() {
        println!("Test 1")
    }

    #[test]
    fn test2() {
        println!("Test 2")
    }
}

This will print:

Setup
Test 1
Test 2
Teardown
Paul Wagener
  • 432
  • 6
  • 12