pub struct Cucumber<W, P, I, R, Wr, Cli = Empty> where
W: World,
P: Parser<I>,
R: Runner<W>,
Wr: Writer<W>,
Cli: Args, { /* private fields */ }
Expand description
Top-level Cucumber executor.
Most of the time you don’t need to work with it directly, just use
WorldInit::run()
or WorldInit::cucumber()
on your World
deriver
to get Cucumber up and running.
Otherwise use Cucumber::new()
to get the default Cucumber executor,
provide Step
s with WorldInit::collection()
or by hand with
Cucumber::given()
, Cucumber::when()
and Cucumber::then()
.
In case you want a custom Parser
, Runner
or Writer
, or some
other finer control, use Cucumber::custom()
or
Cucumber::with_parser()
, Cucumber::with_runner()
and
Cucumber::with_writer()
to construct your dream Cucumber executor!
Implementations
sourceimpl<W, P, I, R, Wr, Cli> Cucumber<W, P, I, R, Wr, Cli> where
W: World,
P: Parser<I>,
R: Runner<W>,
Wr: Writer<W>,
Cli: Args,
impl<W, P, I, R, Wr, Cli> Cucumber<W, P, I, R, Wr, Cli> where
W: World,
P: Parser<I>,
R: Runner<W>,
Wr: Writer<W>,
Cli: Args,
sourcepub fn with_parser<NewP, NewI>(
self,
parser: NewP
) -> Cucumber<W, NewP, NewI, R, Wr, Cli> where
NewP: Parser<NewI>,
pub fn with_parser<NewP, NewI>(
self,
parser: NewP
) -> Cucumber<W, NewP, NewI, R, Wr, Cli> where
NewP: Parser<NewI>,
Replaces Parser
.
sourcepub fn with_runner<NewR>(self, runner: NewR) -> Cucumber<W, P, I, NewR, Wr, Cli> where
NewR: Runner<W>,
pub fn with_runner<NewR>(self, runner: NewR) -> Cucumber<W, P, I, NewR, Wr, Cli> where
NewR: Runner<W>,
Replaces Runner
.
sourcepub fn with_writer<NewWr>(
self,
writer: NewWr
) -> Cucumber<W, P, I, R, NewWr, Cli> where
NewWr: Writer<W>,
pub fn with_writer<NewWr>(
self,
writer: NewWr
) -> Cucumber<W, P, I, R, NewWr, Cli> where
NewWr: Writer<W>,
Replaces Writer
.
sourcepub fn repeat_skipped(self) -> Cucumber<W, P, I, R, Repeat<W, Wr>, Cli> where
Wr: NonTransforming,
pub fn repeat_skipped(self) -> Cucumber<W, P, I, R, Repeat<W, Wr>, Cli> where
Wr: NonTransforming,
Re-outputs Skipped
steps for easier navigation.
Example
Output with a regular Cucumber::run()
:
Adjust Cucumber
to re-output all the Skipped
steps at the end:
MyWorld::cucumber()
.repeat_skipped()
.run_and_exit("tests/features/readme")
.await;
sourcepub fn repeat_failed(self) -> Cucumber<W, P, I, R, Repeat<W, Wr>, Cli> where
Wr: NonTransforming,
pub fn repeat_failed(self) -> Cucumber<W, P, I, R, Repeat<W, Wr>, Cli> where
Wr: NonTransforming,
Re-outputs Failed
steps for easier navigation.
Example
Output with a regular Cucumber::fail_on_skipped()
:
MyWorld::cucumber()
.fail_on_skipped()
.run_and_exit("tests/features/readme")
.await;
Adjust Cucumber
to re-output all the Failed
steps at the end:
MyWorld::cucumber()
.repeat_failed()
.fail_on_skipped()
.run_and_exit("tests/features/readme")
.await;
sourcepub fn repeat_if<F>(
self,
filter: F
) -> Cucumber<W, P, I, R, Repeat<W, Wr, F>, Cli> where
F: Fn(&Result<Event<Cucumber<W>>>) -> bool,
Wr: NonTransforming,
pub fn repeat_if<F>(
self,
filter: F
) -> Cucumber<W, P, I, R, Repeat<W, Wr, F>, Cli> where
F: Fn(&Result<Event<Cucumber<W>>>) -> bool,
Wr: NonTransforming,
Re-outputs steps by the given filter
predicate.
Example
Output with a regular Cucumber::fail_on_skipped()
:
MyWorld::cucumber()
.fail_on_skipped()
.run_and_exit("tests/features/readme")
.await;
Adjust Cucumber
to re-output all the Failed
steps ta the end by
providing a custom filter
predicate:
MyWorld::cucumber()
.repeat_if(|ev| {
use cucumber::event::{Cucumber, Feature, Rule, Scenario, Step};
matches!(
ev.as_deref(),
Ok(Cucumber::Feature(
_,
Feature::Rule(
_,
Rule::Scenario(
_,
Scenario::Step(_, Step::Failed(..))
| Scenario::Background(_, Step::Failed(..))
)
) | Feature::Scenario(
_,
Scenario::Step(_, Step::Failed(..))
| Scenario::Background(_, Step::Failed(..))
)
)) | Err(_)
)
})
.fail_on_skipped()
.run_and_exit("tests/features/readme")
.await;
sourceimpl<W, P, I, R, Wr, Cli> Cucumber<W, P, I, R, Wr, Cli> where
W: World,
P: Parser<I>,
R: Runner<W>,
Wr: Writer<W> + for<'val> Arbitrary<'val, W, String>,
Cli: Args,
impl<W, P, I, R, Wr, Cli> Cucumber<W, P, I, R, Wr, Cli> where
W: World,
P: Parser<I>,
R: Runner<W>,
Wr: Writer<W> + for<'val> Arbitrary<'val, W, String>,
Cli: Args,
sourcepub fn fail_on_skipped(self) -> Cucumber<W, P, I, R, FailOnSkipped<Wr>, Cli>
pub fn fail_on_skipped(self) -> Cucumber<W, P, I, R, FailOnSkipped<Wr>, Cli>
Consider Skipped
Background
or regular Step
s as Failed
if their Scenario
isn’t marked with @allow.skipped
tag.
It’s useful option for ensuring that all the steps were covered.
Example
Output with a regular Cucumber::run()
:
To fail all the Skipped
steps setup Cucumber
like this:
MyWorld::cucumber()
.fail_on_skipped()
.run_and_exit("tests/features/readme")
.await;
To intentionally suppress some Skipped
steps failing, use the
@allow.skipped
tag:
Feature: Animal feature
Scenario: If we feed a hungry cat it will no longer be hungry
Given a hungry cat
When I feed the cat
Then the cat is not hungry
@allow.skipped
Scenario: If we feed a satiated dog it will not become hungry
Given a satiated dog
When I feed the dog
Then the dog is not hungry
sourcepub fn fail_on_skipped_with<Filter>(
self,
filter: Filter
) -> Cucumber<W, P, I, R, FailOnSkipped<Wr, Filter>, Cli> where
Filter: Fn(&Feature, Option<&Rule>, &Scenario) -> bool,
pub fn fail_on_skipped_with<Filter>(
self,
filter: Filter
) -> Cucumber<W, P, I, R, FailOnSkipped<Wr, Filter>, Cli> where
Filter: Fn(&Feature, Option<&Rule>, &Scenario) -> bool,
Consider Skipped
Background
or regular Step
s as Failed
if the given filter
predicate returns true
.
Example
Output with a regular Cucumber::run()
:
Adjust Cucumber
to fail on all Skipped
steps, but the ones
marked with a @dog
tag:
MyWorld::cucumber()
.fail_on_skipped_with(|_, _, s| !s.tags.iter().any(|t| t == "dog"))
.run_and_exit("tests/features/readme")
.await;
Feature: Animal feature
Scenario: If we feed a hungry cat it will no longer be hungry
Given a hungry cat
When I feed the cat
Then the cat is not hungry
Scenario: If we feed a satiated dog it will not become hungry
Given a satiated dog
When I feed the dog
Then the dog is not hungry
And to avoid failing, use the @dog
tag:
Feature: Animal feature
Scenario: If we feed a hungry cat it will no longer be hungry
Given a hungry cat
When I feed the cat
Then the cat is not hungry
@dog
Scenario: If we feed a satiated dog it will not become hungry
Given a satiated dog
When I feed the dog
Then the dog is not hungry
sourceimpl<W, P, I, R, Wr, Cli> Cucumber<W, P, I, R, Wr, Cli> where
W: World,
P: Parser<I>,
R: Runner<W>,
Wr: Writer<W> + Normalized,
Cli: Args,
impl<W, P, I, R, Wr, Cli> Cucumber<W, P, I, R, Wr, Cli> where
W: World,
P: Parser<I>,
R: Runner<W>,
Wr: Writer<W> + Normalized,
Cli: Args,
sourcepub fn with_cli<CustomCli>(
self,
cli: Opts<P::Cli, R::Cli, Wr::Cli, CustomCli>
) -> Cucumber<W, P, I, R, Wr, CustomCli> where
CustomCli: Args,
pub fn with_cli<CustomCli>(
self,
cli: Opts<P::Cli, R::Cli, Wr::Cli, CustomCli>
) -> Cucumber<W, P, I, R, Wr, CustomCli> where
CustomCli: Args,
Consumes already parsed cli::Opts
.
This method allows to pre-parse cli::Opts
for custom needs before
using them inside Cucumber
.
Also, any additional custom CLI options may be specified as a
clap::Args
deriving type, used as the last type parameter of
cli::Opts
.
⚠️ WARNING: Any CLI options of
Parser
,Runner
,Writer
or custom ones should not overlap, otherwisecli::Opts
will fail to parse on startup.
Example
#[derive(clap::Args)]
struct CustomCli {
/// Additional time to wait in a before hook.
#[clap(
long,
parse(try_from_str = humantime::parse_duration)
)]
before_time: Option<Duration>,
}
let cli = cli::Opts::<_, _, _, CustomCli>::parsed();
let time = cli.custom.before_time.unwrap_or_default();
MyWorld::cucumber()
.before(move |_, _, _, _| time::sleep(time).boxed_local())
.with_cli(cli)
.run_and_exit("tests/features/readme")
.await;
Feature: Animal feature
Scenario: If we feed a hungry cat it will no longer be hungry
Given a hungry cat
When I feed the cat
Then the cat is not hungry
Also, specifying --help
flag will describe --before-time
now.
sourcepub async fn filter_run<F>(self, input: I, filter: F) -> Wr where
F: Fn(&Feature, Option<&Rule>, &Scenario) -> bool + 'static,
pub async fn filter_run<F>(self, input: I, filter: F) -> Wr where
F: Fn(&Feature, Option<&Rule>, &Scenario) -> bool + 'static,
Runs Cucumber
with Scenario
s filter.
Feature
s sourced from a Parser
are fed to a Runner
, which
produces events handled by a Writer
.
Example
Adjust Cucumber
to run only Scenario
s marked with @cat
tag:
MyWorld::cucumber()
.filter_run("tests/features/readme", |_, _, sc| {
sc.tags.iter().any(|t| t == "cat")
})
.await;
Feature: Animal feature
@cat
Scenario: If we feed a hungry cat it will no longer be hungry
Given a hungry cat
When I feed the cat
Then the cat is not hungry
@dog
Scenario: If we feed a satiated dog it will not become hungry
Given a satiated dog
When I feed the dog
Then the dog is not hungry
sourceimpl<W, I> Cucumber<W, Basic, I, Basic<W>, Summarize<Normalize<W, Basic>>> where
W: World + Debug,
I: AsRef<Path>,
impl<W, I> Cucumber<W, Basic, I, Basic<W>, Summarize<Normalize<W, Basic>>> where
W: World + Debug,
I: AsRef<Path>,
sourcepub fn new() -> Self
pub fn new() -> Self
Creates a default Cucumber
executor.
-
ScenarioType
—Concurrent
by default,Serial
if@serial
tag is present on aScenario
;- Allowed to run up to 64
Concurrent
Scenario
s.
-
Writer
—Normalize
andSummarize
writer::Basic
.
sourceimpl<W, I, R, Wr, Cli> Cucumber<W, Basic, I, R, Wr, Cli> where
W: World,
R: Runner<W>,
Wr: Writer<W>,
Cli: Args,
I: AsRef<Path>,
impl<W, I, R, Wr, Cli> Cucumber<W, Basic, I, R, Wr, Cli> where
W: World,
R: Runner<W>,
Wr: Writer<W>,
Cli: Args,
I: AsRef<Path>,
sourceimpl<W, I, P, Wr, F, B, A, Cli> Cucumber<W, P, I, Basic<W, F, B, A>, Wr, Cli> where
W: World,
P: Parser<I>,
Wr: Writer<W>,
Cli: Args,
F: Fn(&Feature, Option<&Rule>, &Scenario) -> ScenarioType + 'static,
B: for<'a> Fn(&'a Feature, Option<&'a Rule>, &'a Scenario, &'a mut W) -> LocalBoxFuture<'a, ()> + 'static,
A: for<'a> Fn(&'a Feature, Option<&'a Rule>, &'a Scenario, Option<&'a mut W>) -> LocalBoxFuture<'a, ()> + 'static,
impl<W, I, P, Wr, F, B, A, Cli> Cucumber<W, P, I, Basic<W, F, B, A>, Wr, Cli> where
W: World,
P: Parser<I>,
Wr: Writer<W>,
Cli: Args,
F: Fn(&Feature, Option<&Rule>, &Scenario) -> ScenarioType + 'static,
B: for<'a> Fn(&'a Feature, Option<&'a Rule>, &'a Scenario, &'a mut W) -> LocalBoxFuture<'a, ()> + 'static,
A: for<'a> Fn(&'a Feature, Option<&'a Rule>, &'a Scenario, Option<&'a mut W>) -> LocalBoxFuture<'a, ()> + 'static,
sourcepub fn max_concurrent_scenarios(self, max: impl Into<Option<usize>>) -> Self
pub fn max_concurrent_scenarios(self, max: impl Into<Option<usize>>) -> Self
sourcepub fn which_scenario<Which>(
self,
func: Which
) -> Cucumber<W, P, I, Basic<W, Which, B, A>, Wr, Cli> where
Which: Fn(&Feature, Option<&Rule>, &Scenario) -> ScenarioType + 'static,
pub fn which_scenario<Which>(
self,
func: Which
) -> Cucumber<W, P, I, Basic<W, Which, B, A>, Wr, Cli> where
Which: Fn(&Feature, Option<&Rule>, &Scenario) -> ScenarioType + 'static,
Function determining whether a Scenario
is Concurrent
or
a Serial
one.
sourcepub fn before<Before>(
self,
func: Before
) -> Cucumber<W, P, I, Basic<W, F, Before, A>, Wr, Cli> where
Before: for<'a> Fn(&'a Feature, Option<&'a Rule>, &'a Scenario, &'a mut W) -> LocalBoxFuture<'a, ()> + 'static,
pub fn before<Before>(
self,
func: Before
) -> Cucumber<W, P, I, Basic<W, F, Before, A>, Wr, Cli> where
Before: for<'a> Fn(&'a Feature, Option<&'a Rule>, &'a Scenario, &'a mut W) -> LocalBoxFuture<'a, ()> + 'static,
Sets a hook, executed on each Scenario
before running all its
Step
s, including Background
ones.
sourcepub fn after<After>(
self,
func: After
) -> Cucumber<W, P, I, Basic<W, F, B, After>, Wr, Cli> where
After: for<'a> Fn(&'a Feature, Option<&'a Rule>, &'a Scenario, Option<&'a mut W>) -> LocalBoxFuture<'a, ()> + 'static,
pub fn after<After>(
self,
func: After
) -> Cucumber<W, P, I, Basic<W, F, B, After>, Wr, Cli> where
After: for<'a> Fn(&'a Feature, Option<&'a Rule>, &'a Scenario, Option<&'a mut W>) -> LocalBoxFuture<'a, ()> + 'static,
Sets a hook, executed on each Scenario
after running all its
Step
s, even after Skipped
of Failed
Step
s.
Last World
argument is supplied to the function, in case it was
initialized before by running before
hook or any non-failed
Step
. In case the last Scenario
’s Step
failed, we want to
return event with an exact World
state. Also, we don’t want to impose
additional Clone
bounds on World
, so the only option left is to
pass None
to the function.
sourcepub fn steps(self, steps: Collection<W>) -> Self
pub fn steps(self, steps: Collection<W>) -> Self
Replaces Collection
of Step
s.
sourceimpl<W, I, P, R, Wr, Cli> Cucumber<W, P, I, R, Wr, Cli> where
W: World,
P: Parser<I>,
R: Runner<W>,
Wr: Failure<W> + Normalized,
Cli: Args,
impl<W, I, P, R, Wr, Cli> Cucumber<W, P, I, R, Wr, Cli> where
W: World,
P: Parser<I>,
R: Runner<W>,
Wr: Failure<W> + Normalized,
Cli: Args,
sourcepub async fn run_and_exit(self, input: I)
pub async fn run_and_exit(self, input: I)
sourcepub async fn filter_run_and_exit<Filter>(self, input: I, filter: Filter) where
Filter: Fn(&Feature, Option<&Rule>, &Scenario) -> bool + 'static,
pub async fn filter_run_and_exit<Filter>(self, input: I, filter: Filter) where
Filter: Fn(&Feature, Option<&Rule>, &Scenario) -> bool + 'static,
Runs Cucumber
with Scenario
s filter.
Feature
s sourced from a Parser
are fed to a Runner
, which
produces events handled by a Writer
.
Panics
If encountered errors while parsing Feature
s or at least one
Step
Failed
.
Example
Adjust Cucumber
to run only Scenario
s marked with @cat
tag:
MyWorld::cucumber()
.filter_run_and_exit("tests/features/readme", |_, _, sc| {
sc.tags.iter().any(|t| t == "cat")
})
.await;
Feature: Animal feature
@cat
Scenario: If we feed a hungry cat it will no longer be hungry
Given a hungry cat
When I feed the cat
Then the cat is not hungry
@dog
Scenario: If we feed a satiated dog it will not become hungry
Given a satiated dog
When I feed the dog
Then the dog is not hungry
Trait Implementations
Auto Trait Implementations
impl<W, P, I, R, Wr, Cli> RefUnwindSafe for Cucumber<W, P, I, R, Wr, Cli> where
Cli: RefUnwindSafe,
I: RefUnwindSafe,
P: RefUnwindSafe,
R: RefUnwindSafe,
W: RefUnwindSafe,
Wr: RefUnwindSafe,
<P as Parser<I>>::Cli: RefUnwindSafe,
<R as Runner<W>>::Cli: RefUnwindSafe,
<Wr as Writer<W>>::Cli: RefUnwindSafe,
impl<W, P, I, R, Wr, Cli> Send for Cucumber<W, P, I, R, Wr, Cli> where
Cli: Send,
I: Send,
P: Send,
R: Send,
W: Send,
Wr: Send,
<P as Parser<I>>::Cli: Send,
<R as Runner<W>>::Cli: Send,
<Wr as Writer<W>>::Cli: Send,
impl<W, P, I, R, Wr, Cli> Sync for Cucumber<W, P, I, R, Wr, Cli> where
Cli: Sync,
I: Sync,
P: Sync,
R: Sync,
W: Sync,
Wr: Sync,
<P as Parser<I>>::Cli: Sync,
<R as Runner<W>>::Cli: Sync,
<Wr as Writer<W>>::Cli: Sync,
impl<W, P, I, R, Wr, Cli> Unpin for Cucumber<W, P, I, R, Wr, Cli> where
Cli: Unpin,
I: Unpin,
P: Unpin,
R: Unpin,
W: Unpin,
Wr: Unpin,
<P as Parser<I>>::Cli: Unpin,
<R as Runner<W>>::Cli: Unpin,
<Wr as Writer<W>>::Cli: Unpin,
impl<W, P, I, R, Wr, Cli> UnwindSafe for Cucumber<W, P, I, R, Wr, Cli> where
Cli: UnwindSafe,
I: UnwindSafe,
P: UnwindSafe,
R: UnwindSafe,
W: UnwindSafe,
Wr: UnwindSafe,
<P as Parser<I>>::Cli: UnwindSafe,
<R as Runner<W>>::Cli: UnwindSafe,
<Wr as Writer<W>>::Cli: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<T> Ext for T
impl<T> Ext for T
sourcefn assert_normalized(self) -> AssertNormalized<T>
fn assert_normalized(self) -> AssertNormalized<T>
Asserts this Writer
being Normalized
. Read more
sourcefn normalized<W>(self) -> Normalize<W, T>
fn normalized<W>(self) -> Normalize<W, T>
sourcefn summarized(self) -> Summarize<T>
fn summarized(self) -> Summarize<T>
sourcefn fail_on_skipped(
self
) -> FailOnSkipped<T, fn(&Feature, Option<&Rule>, &Scenario) -> bool>
fn fail_on_skipped(
self
) -> FailOnSkipped<T, fn(&Feature, Option<&Rule>, &Scenario) -> bool>
sourcefn fail_on_skipped_with<F>(self, f: F) -> FailOnSkipped<T, F> where
F: Fn(&Feature, Option<&Rule>, &Scenario) -> bool,
fn fail_on_skipped_with<F>(self, f: F) -> FailOnSkipped<T, F> where
F: Fn(&Feature, Option<&Rule>, &Scenario) -> bool,
sourcefn repeat_if<W, F>(self, filter: F) -> Repeat<W, T, F> where
F: Fn(&Result<Event<Cucumber<W>>, Error>) -> bool,
fn repeat_if<W, F>(self, filter: F) -> Repeat<W, T, F> where
F: Fn(&Result<Event<Cucumber<W>>, Error>) -> bool,
sourcefn discard_arbitrary_writes(self) -> Arbitrary<T>
fn discard_arbitrary_writes(self) -> Arbitrary<T>
Wraps this Writer
into a discard::Arbitrary
one, providing a
no-op ArbitraryWriter
implementation. Read more
sourcefn discard_failure_writes(self) -> Failure<T>
fn discard_failure_writes(self) -> Failure<T>
Wraps this Writer
into a discard::Arbitrary
one, providing a
no-op FailureWriter
implementation returning only 0
. Read more