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
World::run()
or World::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 World::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, RetryableScenario, Rule, Scenario, Step,
};
matches!(
ev.as_deref(),
Ok(Cucumber::Feature(
_,
Feature::Rule(
_,
Rule::Scenario(
_,
RetryableScenario {
event: Scenario::Step(_, Step::Failed(..))
| Scenario::Background(
_,
Step::Failed(_, _, _, _),
),
retries: _
}
)
) | Feature::Scenario(
_,
RetryableScenario {
event: Scenario::Step(_, Step::Failed(..))
| Scenario::Background(_, Step::Failed(..)),
retries: _
}
)
)) | Err(_)
)
})
.fail_on_skipped()
.run_and_exit("tests/features/readme")
.await;
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) -> Wrwhere
F: Fn(&Feature, Option<&Rule>, &Scenario) -> bool + 'static,
pub async fn filter_run<F>(self, input: I, filter: F) -> Wrwhere
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 retries(self, retries: impl Into<Option<usize>>) -> Self
pub fn retries(self, retries: impl Into<Option<usize>>) -> Self
Makes failed Scenario
s being retried the specified number of times.
sourcepub fn retry_after(self, after: impl Into<Option<Duration>>) -> Self
pub fn retry_after(self, after: impl Into<Option<Duration>>) -> Self
sourcepub fn retry_filter(
self,
tag_expression: impl Into<Option<TagOperation>>
) -> Self
pub fn retry_filter(
self,
tag_expression: impl Into<Option<TagOperation>>
) -> Self
Makes failed Scenario
s being retried only if they’re matching the
specified tag_expression
.
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 retry_options<Retry>(self, func: Retry) -> Selfwhere
Retry: Fn(&Feature, Option<&Rule>, &Scenario, &Cli) -> Option<RetryOptions> + 'static,
pub fn retry_options<Retry>(self, func: Retry) -> Selfwhere
Retry: Fn(&Feature, Option<&Rule>, &Scenario, &Cli) -> Option<RetryOptions> + 'static,
Function determining Scenario
’s RetryOptions
.
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,
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: Stats<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: Stats<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 Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
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_stats_writes(self) -> Stats<T>
fn discard_stats_writes(self) -> Stats<T>
Wraps this Writer
into a discard::Stats
one, providing a no-op
StatsWriter
implementation returning only 0
. Read more