4 releases (2 stable)
1.1.0 | Jun 5, 2024 |
---|---|
1.0.0 | Apr 9, 2022 |
0.2.0 | Feb 5, 2022 |
0.1.0 | Dec 7, 2021 |
#77 in Filesystem
18,180 downloads per month
Used in 15 crates
15KB
145 lines
Sealed test
This crate exposes the #[sealed_test]
macro attribute to run your tests in an isolated environment.
It provides the following :
- an isolated process using rusty-fork
- a temporary work dir with tempfile.
- a set of handy attributes to configure your tests including:
before
/after
: setup and teardown functions for your tests.env
: set environment variables in the test process.files
: copy files from your crate directory to the test temporary directory.
Caution: using #[sealed_test]
instead of #[test]
will create a temporary file
and set it to be the test current directory but, nothing stops you from changing that directory
using std::env::set_current_dir
.
Why ?
If you run cargo test
your tests will run in parallel, in some case this could be problematic.
Let us examine a concrete example.
#[test]
fn foo() -> Result<(), VarError> {
std::env::set_var("VAR", "foo");
let var = std::env::var("VAR")?;
assert_eq!(var, "foo");
Ok(())
}
#[test]
fn bar() -> Result<(), VarError> {
std::env::set_var("VAR", "bar");
// During the thread sleep, the `foo` test will run
// and set the environment variable to "foo"
std::thread::sleep(Duration::from_secs(1));
let var = std::env::var("VAR")?;
// If running tests on multiple threads the below assertion will fail
assert_eq!(var, "bar");
Ok(())
}
With sealed_test
Here each test has its own environment, the tests will always pass !
use sealed_test::prelude::*;
#[sealed_test]
fn foo() -> Result<(), VarError> {
std::env::set_var("VAR", "bar");
let var = std::env::var("VAR")?;
assert_eq!(var, "bar");
Ok(())
}
#[sealed_test]
fn bar() -> Result<(), VarError> {
std::env::set_var("VAR", "bar");
std::thread::sleep(Duration::from_secs(1));
let var = std::env::var("VAR")?;
assert_eq!(var, "bar");
Ok(())
}
Examples
The env
attribute
The env
attribute allow to quickly set environment variable in your tests.
This is only syntactic sugar and you can still normally manipulate environment variables with std::env
.
#[sealed_test(env = [ ("FOO", "foo"), ("BAR", "bar") ])]
fn should_set_env() {
let foo = std::env::var("FOO").expect("Failed to get $FOO");
let bar = std::env::var("BAR").expect("Failed to get $BAR");
assert_eq!(foo, "foo");
assert_eq!(bar, "bar");
}
Tip: Sealed tests have their own environment and variable from the parent won't be affected by whatever you do with the test environment.
The files
attribute
If you need test behaviors that mutate the file system, you can use the files
attribute to quickly copy files from your crate root to the test working directory.
The test working directory lives in tmpfs and will be cleaned up after the test execution.
#[sealed_test(files = ["tests/foo", "tests/bar"])]
fn should_copy_files() {
assert!(PathBuf::from("foo").exists());
assert!(PathBuf::from("bar").exists());
}
Setup and teardown
Use before
and after
to run a rust expression around your tests, typically a function, for instance setup = setup_function()
.
before
and after
#[sealed_test(before = setup(), after = teardown())]
fn should_run_setup_and_tear_down() {
// ...
}
fn setup() {
println!("Hello from setup")
}
fn teardown() {
println!("Hello from teardown")
}
Dependencies
~2–11MB
~134K SLoC