I want to write test cases that depend on parameters. My test case should be executed for each parameter and I want to see whether it succeeds or fails for each parameter.
It's possible to construct tests based on arbitrarily complex parameters and any information known at build time (including anything you can load from a file) with a build script.
We tell Cargo where the build script is:
Cargo.toml
[package]
name = "test"
version = "0.1.0"
build = "build.rs"
In the build script, we generate our test logic and place it in a file using the environment variable OUT_DIR
:
build.rs
fn main() {
let out_dir = std::env::var("OUT_DIR").unwrap();
let destination = std::path::Path::new(&out_dir).join("test.rs");
let mut f = std::fs::File::create(&destination).unwrap();
let params = &["abc", "fooboo"];
for p in params {
use std::io::Write;
write!(
f,
"
#[test]
fn {name}() {{
assert!(true);
}}",
name = p
).unwrap();
}
}
Finally, we create a file in our tests directory that includes the code of the generated file.
tests/generated_test.rs
include!(concat!(env!("OUT_DIR"), "/test.rs"));
That's it. Let's verify that the tests are run:
$ cargo test
Compiling test v0.1.0 (...)
Finished debug [unoptimized + debuginfo] target(s) in 0.26 secs
Running target/debug/deps/generated_test-ce82d068f4ceb10d
running 2 tests
test abc ... ok
test fooboo ... ok