rstest
's parametrized cases:warning: Version 0.5.0 introduce a breaking change
This crate give a way to define a tests set and apply them to every case you need to
test. With rstest
crate you can define a tests list but if you want to apply the same tests
to another test function you must rewrite all cases or write some macros that do the job.
Both solutions have some drawbreak: - intruduce duplication - macros makes code harder to read and shift out the focus from tests core
The aim of this crate is solve this problem. rstest_resuse
expose two attributes:
- #[template]
: to define a template
- #[apply]
: to apply a defined template to create tests
Here is a simple example:
``rust
use rstest::rstest;
use rstest_reuse::{self, *};
// Here we define the template. This define
// * The test list name to
twosimplecases`
// * cases: here two cases
// Define a and b as cases arguments
fn twosimplecases(#[case] a: u32, #[case] b: u32) {}
// Here we apply the two_simple_cases
template: That is expanded in
// #[template]
// #[rstest]
// #[case(2, 2)]
// #[case(4/2, 2)]
// fn it_works(#[case] a: u32,#[case] b: u32) {
// assert!(a == b);
// }
fn it_works(a: u32, b: u32) {
assert!(a == b);
}
// Here we reuse the two_simple_cases
template to create two
// other tests
fn it_fail(a: u32, b: u32) { assert!(a != b); } ```
If we run cargo test
we have:
text
Finished test [unoptimized + debuginfo] target(s) in 0.05s
Running target/debug/deps/playground-8a1212f8b5eb00ce
running 4 tests
test it_fail::case_1 ... FAILED
test it_works::case_1 ... ok
test it_works::case_2 ... ok
test it_fail::case_2 ... FAILED
failures:
---- it_fail::case_1 stdout ----
thread 'it_fail::case_1' panicked at 'assertion failed: a != b', src/main.rs:34:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
---- it_fail::case_2 stdout ----
thread 'it_fail::case_2' panicked at 'assertion failed: a != b', src/main.rs:34:5
failures:
it_fail::case_1
it_fail::case_2
test result: FAILED. 2 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out
error: test failed, to rerun pass '--bin playground'
Simple and neat!
Note that if the test arguments names match the template's ones you can don't repeate the arguments attributes.
If you need to add some cases or values when apply a template you can leverage on composition. Here a simple example:
```rust
fn base(#[case] a: u32, #[case] b: u32) {}
// Here we add a new case and an argument in a value list:
fn it_works(a: u32, b: u32, #[values("a", "b")] t: &str) { assert!(a == b); assert!("abcd".contains(t)) } ```
run 6 tests:
running 6 tests
test it_works::case_1::t_2 ... ok
test it_works::case_2::t_2 ... ok
test it_works::case_2::t_1 ... ok
test it_works::case_3::t_2 ... ok
test it_works::case_3::t_1 ... ok
test it_works::case_1::t_1 ... ok
Template can also used for values and with arguments if you need:
```rust
fn base(#[with(42)] fix: u32, #[values(1,2,3)] v: u32) {}
fn fix(#[default(0)] inner: u32) -> u32 { inner }
fn useitwith_fixture(fix: u32, v: u32) { assert!(fix%v == 0); }
fn useitwithout_fixture(v: u32) { assert!(24 % v == 0); } ```
Run also 6 tests:
running 6 tests
test use_it_with_fixture::v_1 ... ok
test use_it_without_fixture::v_1 ... ok
test use_it_with_fixture::v_3 ... ok
test use_it_without_fixture::v_2 ... ok
test use_it_without_fixture::v_3 ... ok
test use_it_with_fixture::v_2 ... ok
use rstest_resuse
at the top of your crateYou should add use rstest_resuse
at the top of your crate:
```rust
use rstest_reuse; ```
This is due rstest_reuse::template
define a macro that need to call a rstest_resuse
's macro.
I hope to remove this in the future but for now we should live with it.
Note that
rust
use rstest_reuse::*;
is not enougth: this statment doesn't include rstest_reuse
but just its public items.
#[export]
Attribute:warning: Version 0.5.0 introduce a breaking change
Now #[export]
attribute give you the possibility to export your template across crates
but don't lift the macro definition at the top of your crate (that was the default behaviour
prior the 0.5.0 version).
Now if you want put your template at the root of your crate you can define it in the root module or reexport it at the top with something like the following line at the top of your crate:
rust
pub use my::modules::path::of::my::template::my_template;
When you want to export your template you should also take care to declare rstest_reuse
as pub
at the top of your crate to enable to use it from the modules that would import the template.
So in this case in the crate that would export template you should put at the root of your crate
```rust
pub use rstest_reuse; ```
And not just use rstest_reuse
like in the standard cases.
#[macro_use]
Attribute Support:warning: Version 0.5.0 introduce a breaking change
Till version 0.4.0 you can use #[macro_use]
to annotate your modules and lift your
macro template to the up level. Now rstest
leverege only on import and paths like all
othter function and original macro is hidden by a random name.
So now if you would use your template from other module you should import it like any other symbol.
```rust mod inner { pub(crate) mod sub { use rstestreuse::*; #[template] #[rstest(a, b, case(2, 2), case(4/2, 2), ) ] fn twosimplecases(a: u32, b: u32) {} } } use rstestreuse::; use rstest::;
fn itworksby_path(a: u32, b: u32) { assert!(a == b); }
use inner::sub::twosimplecases
fn itworksafter_use(a: u32, b: u32) { assert!(a == b); }
```
This crate is in a development stage. I don't know if I'll include it in rstest
or change some syntax in the future.
I did't test it in a lot of cases: if you have some cases where it doesn't works file a ticket on rstest
Licensed under either of
Apache License, Version 2.0, (LICENSE-APACHE or [license-apache-link])
MIT license LICENSE-MIT or [license-MIT-link] at your option.