Guides · 4 of 7
Bind and filter scenarios
A scenario becomes a test when something binds it: #[scenario] for one, scenarios! for a directory. Tags decide which, and skip! says why one did not run.
One scenario
#[scenario] turns a function into the test for one
scenario. path names the feature file, relative to
the crate root; name picks a scenario by title, or
index by position, and without either the first
scenario is used.
#[scenario(path = "tests/features/hamper.feature", name = "Pack the picnic")]
fn pack_the_picnic(hamper: Hamper) {
let _ = hamper;
}
Compiled and run against rstest-bdd 0.6.0.
The function’s parameters are the scenario’s fixtures, and its body runs after the last step. A name that matches no scenario, or more than one, is a compile error.
A whole directory
scenarios! walks a directory and generates a test for
every scenario it finds, named from the file and the scenario
title. Fixtures the steps need are listed with their types, since
there is no function signature to declare them.
//! The `scenarios!` macro auto-discovering feature files, tag filtering, and
//! a step that skips a scenario at runtime.
use rstest::fixture;
use rstest_bdd_macros::{given, scenarios, then};
#[derive(Default)]
struct Evening {
forecast: String,
}
#[fixture]
fn evening() -> Evening {
Evening::default()
}
#[given("the forecast is \"{forecast}\"")]
fn forecast(evening: &mut Evening, forecast: String) {
if forecast == "thunder" {
rstest_bdd::skip!("no picnics in a thunderstorm");
}
evening.forecast = forecast;
}
#[then("the blanket goes on the grass")]
fn blanket(evening: &Evening) {
assert_eq!(evening.forecast, "dry");
}
#[then("the lanterns are lit early")]
fn lanterns(evening: &Evening) {
assert_eq!(evening.forecast, "fog");
}
scenarios!(
"tests/features/auto",
tags = "@smoke and not @wip",
fixtures = [evening: Evening]
);
Compiled and run against rstest-bdd 0.6.0.
running 2 tests test auto_scenarios::weather_thunder_in_the_hills ... ok test auto_scenarios::weather_a_dry_evening ... ok test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Skipping
A step that cannot sensibly go on calls
rstest_bdd::skip! with a reason. The remaining steps
and the scenario body do not run. The thunder scenario above does
exactly that:
#[given("the forecast is \"{forecast}\"")]
fn forecast(evening: &mut Evening, forecast: String) {
if forecast == "thunder" {
rstest_bdd::skip!("no picnics in a thunderstorm");
}
evening.forecast = forecast;
}
Compiled and run against rstest-bdd 0.6.0.
A skipped scenario still reports ok, which is easy to
miss. Set RSTEST_BDD_FAIL_ON_SKIPPED=1 and every skip
fails the test, unless its feature or scenario carries
@allow_skipped, as the thunder does.
$ RSTEST_BDD_FAIL_ON_SKIPPED=1 cargo test --test weather
cargo bdd skipped --reasons lists every skip and its
reason; see tooling.