pub struct Cucumber<W, P, I, R, Wr, Cli = Empty>{ /* 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§
source§impl<W, P, I, R, Wr, Cli> Cucumber<W, P, I, R, Wr, Cli>
impl<W, P, I, R, Wr, Cli> Cucumber<W, P, I, R, Wr, Cli>
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>
pub fn repeat_if<F>( self, filter: F ) -> Cucumber<W, P, I, R, Repeat<W, Wr, F>, Cli>
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>
pub fn fail_on_skipped_with<Filter>( self, filter: Filter ) -> Cucumber<W, P, I, R, FailOnSkipped<Wr, Filter>, Cli>
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
source§impl<W, P, I, R, Wr, Cli> Cucumber<W, P, I, R, Wr, Cli>
impl<W, P, I, R, Wr, Cli> Cucumber<W, P, I, R, Wr, Cli>
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.
#[arg(
long,
value_parser = 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 fn with_default_cli(self) -> Self
pub fn with_default_cli(self) -> Self
sourcepub async fn filter_run<F>(self, input: I, filter: F) -> Wr
pub async fn filter_run<F>(self, input: I, filter: F) -> Wr
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
source§impl<W, I> Cucumber<W, Basic, I, Basic<W>, Summarize<Normalize<W, Basic>>>
impl<W, I> Cucumber<W, Basic, I, Basic<W>, Summarize<Normalize<W, Basic>>>
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
.
source§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, &'a ScenarioFinished, 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, &'a ScenarioFinished, 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>
pub fn which_scenario<Which>( self, func: Which ) -> Cucumber<W, P, I, Basic<W, Which, B, A>, Wr, Cli>
Function determining whether a Scenario
is Concurrent
or
a Serial
one.
sourcepub fn retry_options<Retry>(self, func: Retry) -> Self
pub fn retry_options<Retry>(self, func: Retry) -> Self
Function determining Scenario
’s RetryOptions
.
sourcepub fn before<Before>(
self,
func: Before
) -> Cucumber<W, P, I, Basic<W, F, Before, A>, Wr, Cli>
pub fn before<Before>( self, func: Before ) -> Cucumber<W, P, I, Basic<W, F, Before, A>, Wr, Cli>
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, &'a ScenarioFinished, 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, &'a ScenarioFinished, 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.
source§impl<W, I, P, R, Wr, Cli> Cucumber<W, P, I, R, Wr, Cli>
impl<W, I, P, R, Wr, Cli> Cucumber<W, P, I, R, Wr, Cli>
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)
pub async fn filter_run_and_exit<Filter>(self, input: I, filter: Filter)
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
source§impl<W, P, I, Wr, Cli, WhichSc, Before, After> Cucumber<W, P, I, Basic<W, WhichSc, Before, After>, Wr, Cli>
impl<W, P, I, Wr, Cli, WhichSc, Before, After> Cucumber<W, P, I, Basic<W, WhichSc, Before, After>, Wr, Cli>
sourcepub fn init_tracing(self) -> Self
Available on crate feature tracing
only.
pub fn init_tracing(self) -> Self
tracing
only.Initializes a global [tracing::Subscriber
] with a default
fmt::Layer
and [LevelFilter::INFO
].
sourcepub fn configure_and_init_tracing<Event, Fields, Sub, Conf, Out>(
self,
fmt_fields: Fields,
event_format: Event,
configure: Conf
) -> Selfwhere
Fields: for<'a> FormatFields<'a> + 'static,
Event: FormatEvent<Sub, SkipScenarioIdSpan<Fields>> + 'static,
Sub: Subscriber + for<'a> LookupSpan<'a>,
Out: Subscriber + Send + Sync,
Conf: FnOnce(Layered<Layer<Sub, SkipScenarioIdSpan<Fields>, AppendScenarioMsg<Event>, CollectorWriter>, RecordScenarioId, Sub>) -> Out,
Available on crate feature tracing
only.
pub fn configure_and_init_tracing<Event, Fields, Sub, Conf, Out>(
self,
fmt_fields: Fields,
event_format: Event,
configure: Conf
) -> Selfwhere
Fields: for<'a> FormatFields<'a> + 'static,
Event: FormatEvent<Sub, SkipScenarioIdSpan<Fields>> + 'static,
Sub: Subscriber + for<'a> LookupSpan<'a>,
Out: Subscriber + Send + Sync,
Conf: FnOnce(Layered<Layer<Sub, SkipScenarioIdSpan<Fields>, AppendScenarioMsg<Event>, CollectorWriter>, RecordScenarioId, Sub>) -> Out,
tracing
only.Configures a fmt::Layer
, additionally wraps it (for example, into a
[LevelFilter
]), and initializes as a global [tracing::Subscriber
].
Example
World::cucumber()
.configure_and_init_tracing(
format::DefaultFields::new(),
Format::default(),
|fmt_layer| {
tracing_subscriber::registry()
.with(LevelFilter::INFO.and_then(fmt_layer))
},
)
.run_and_exit("./tests/features/doctests.feature")
.await
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>
impl<W, P, I, R, Wr, Cli> Sync for Cucumber<W, P, I, R, Wr, Cli>
impl<W, P, I, R, Wr, Cli> Unpin for Cucumber<W, P, I, R, Wr, Cli>
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§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> Ext for T
impl<T> Ext for T
source§fn assert_normalized(self) -> AssertNormalized<T>
fn assert_normalized(self) -> AssertNormalized<T>
source§fn normalized<W>(self) -> Normalize<W, T>
fn normalized<W>(self) -> Normalize<W, T>
source§fn summarized(self) -> Summarize<T>
fn summarized(self) -> Summarize<T>
source§fn fail_on_skipped(self) -> FailOnSkipped<T>
fn fail_on_skipped(self) -> FailOnSkipped<T>
source§fn fail_on_skipped_with<F>(self, f: F) -> FailOnSkipped<T, F>
fn fail_on_skipped_with<F>(self, f: F) -> FailOnSkipped<T, F>
source§fn repeat_skipped<W>(self) -> Repeat<W, T>
fn repeat_skipped<W>(self) -> Repeat<W, T>
source§fn repeat_failed<W>(self) -> Repeat<W, T>
fn repeat_failed<W>(self) -> Repeat<W, T>
source§fn repeat_if<W, F>(self, filter: F) -> Repeat<W, T, F>
fn repeat_if<W, F>(self, filter: F) -> Repeat<W, T, F>
Writer
to re-output filter
ed events at the end of an
output.source§fn tee<W, Wr>(self, other: Wr) -> Tee<T, Wr>where
Wr: Writer<W>,
fn tee<W, Wr>(self, other: Wr) -> Tee<T, Wr>where
Wr: Writer<W>,
other
Writer
to the current one for passing
events to both of them simultaneously.source§fn discard_arbitrary_writes(self) -> Arbitrary<T>
fn discard_arbitrary_writes(self) -> Arbitrary<T>
Writer
into a discard::Arbitrary
one, providing a
no-op ArbitraryWriter
implementation. Read moresource§fn discard_stats_writes(self) -> Stats<T>
fn discard_stats_writes(self) -> Stats<T>
Writer
into a discard::Stats
one, providing a no-op
StatsWriter
implementation returning only 0
. Read more