Crates.io | sealed_test |
lib.rs | sealed_test |
version | 1.1.0 |
source | src |
created_at | 2021-12-07 16:10:06.414254 |
updated_at | 2024-06-05 05:55:25.949845 |
description | A procmacro attribute to run your test in an isolated environment |
homepage | |
repository | https://github.com/oknozor/sealed-test |
max_upload_size | |
id | 493918 |
size | 16,090 |
This crate exposes the #[sealed_test]
macro attribute to run your tests in an isolated environment.
It provides the following :
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
.
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(())
}
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(())
}
env
attributeThe 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.
files
attributeIf 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());
}
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")
}