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.
EDIT: This is now on crates.io as parameterized_test::create!{...}
- Add parameterized_test = "0.1.0"
to your Cargo.toml
file.
Building off Chris Morgan’s answer, here's a recursive macro to create parameterized tests (playground):
macro_rules! parameterized_test {
($name:ident, $args:pat, $body:tt) => {
with_dollar_sign! {
($d:tt) => {
macro_rules! $name {
($d($d pname:ident: $d values:expr,)*) => {
mod $name {
use super::*;
$d(
#[test]
fn $d pname() {
let $args = $d values;
$body
}
)*
}}}}}}}
You can use it like so:
parameterized_test!{ even, n, { assert_eq!(n % 2, 0); } }
even! {
one: 1,
two: 2,
}
parameterized_test!
defines a new macro (even!
) that will create parameterized tests taking one argument (n
) and invoking assert_eq!(n % 2, 0);
.
even!
then works essentially like Chris' fib_tests!
, though it groups the tests into a module so they can share a prefix (suggested here). This example results in two tests functions, even::one
and even::two
.
This same syntax works for multiple parameters:
parameterized_test!{equal, (actual, expected), {
assert_eq!(actual, expected);
}}
equal! {
same: (1, 1),
different: (2, 3),
}
The with_dollar_sign!
macro used above to essentially escape the dollar-signs in the inner macro comes from @durka:
macro_rules! with_dollar_sign {
($($body:tt)*) => {
macro_rules! __with_dollar_sign { $($body)* }
__with_dollar_sign!($);
}
}
I've not written many Rust macros before, so feedback and suggestions are very welcome.