Sif provides a procedural macro which allows you to define a test to be run with multiple arguments.
Test cases are defined using the 'parameterized' attribute instead of the 'test' attribute.
This crate was inspired by the JUnit @ParameterizedTest
annotation and builds on the development experience of the
parameterized crate.
Aside from the two examples below you can find additional examples in the sif_demo crate in this repository and in the tests folder.
Example: NPCs
#[cfg(test)] #[macro_use] extern crate sif;
enum NPC {
Andre,
Lautrec,
Siegmeyer,
Solaire,
}
trait Home {
fn reigns_from(&self) -> &str;
}
impl Home for NPC {
fn reigns_from(&self) -> &str {
match self {
NPC::Solaire | NPC::Andre => "Astora",
NPC::Lautrec => "Carim",
NPC::Siegmeyer => "Catarina",
}
}
}
#[parameterized]
#[case(NPC::Andre, "Astora")]
#[case(NPC::Lautrec, "Carim")]
#[case(NPC::Siegmeyer, "Catarina")]
#[case(NPC::Solaire, "Astora")]
fn npc_reigns_from_test(npc: NPC, place: &str) {
assert_eq!(npc.reigns_from(), place)
}
With Rust 2018, there are two primary ways to import an attribute macro.
The first is by importing the macro into the local scope like a regular import, for example: use sif::parameterized;
.
This method also makes it easy to alias the macro's attribute to some other identifier, e.g. use sif::parameterized as pm;
.
The second is by using extern crate
in combination with the macro_use
attribute (for example: #[cfg(test)] #[macro_use] extern crate sif;
).
This second option has an advantage if you use the macro a lot in your crate, since you only have to import it once at the root of the crate.
IntelliJ IDEA recognises test cases and provides context menus which allow you to run tests within a certain scope
(such as a module or a single test case), for example by clicking the ▶ icon in the gutter next to
the start of a block containing a #[test]
. Unfortunately, as attribute macros are currently not expanded,
the IDE will not recognise the test cases generated by the sif::parameterized
macro. Since I find this way of running tests
rather useful, I opted to implement a simple workaround by providing a small declarative macro which expands to an empty test case.
#[cfg(test)] #[macro_use] extern crate sif;
fn squared(input: i8) -> i8 {
input * input
}
#[cfg(test)]
/*▶*/mod tests {
use super::*;
/*▶*/mod squared_tests { // <--
use super::*;
// this macro generates an empty test case which will mark the module as containing tests.
ide!(); // <--
#[parameterized]
#[case(-2, 4)]
#[case(-1, 1)]
#[case(0, 0)]
#[case(1, 4)]
fn test_squared(input: i8, output: i8) {
assert_eq(squared(input), output);
}
}
}
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.