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 Steps 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 Steps 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 hungrySourcepub 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 Steps 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 hungryAnd 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 hungrySource§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,Writeror custom ones should not overlap, otherwisecli::Optswill 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 hungryAlso, 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 Scenarios filter.
Features sourced from a Parser are fed to a Runner, which
produces events handled by a Writer.
§Example
Adjust Cucumber to run only Scenarios 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 hungrySource§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—Concurrentby default,Serialif@serialtag is present on aScenario;- Allowed to run up to 64
ConcurrentScenarios.
-
Writer—NormalizeandSummarizewriter::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 Scenarios 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 Scenarios 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
Steps, including Background ones.
NOTE: Only one
beforehook can be registered. If multiple calls are made, only the last one will be run.
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,
Sets a hook, executed on each Scenario after running all its
Steps, even after Skipped of Failed Steps.
NOTE: Only one
afterhook can be registered. If multiple calls are made, only the last one will be run.
Last World argument is supplied to the function, in case it was
initialized before by running before hook or any Step.
Sourcepub fn steps(self, steps: Collection<W>) -> Self
pub fn steps(self, steps: Collection<W>) -> Self
Replaces Collection of Steps.
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 Scenarios filter.
Features sourced from a Parser are fed to a Runner, which
produces events handled by a Writer.
§Panics
If encountered errors while parsing Features or at least one
Step Failed.
§Example
Adjust Cucumber to run only Scenarios 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 hungrySource§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")
.awaitTrait Implementations§
Auto Trait Implementations§
impl<W, P, I, R, Wr, Cli> Freeze for Cucumber<W, P, I, R, Wr, Cli>
impl<W, P, I, R, Wr, Cli> RefUnwindSafe for Cucumber<W, P, I, R, Wr, Cli>where
P: RefUnwindSafe,
R: RefUnwindSafe,
Wr: RefUnwindSafe,
W: RefUnwindSafe,
I: RefUnwindSafe,
<P as Parser<I>>::Cli: RefUnwindSafe,
<R as Runner<W>>::Cli: RefUnwindSafe,
<Wr as Writer<W>>::Cli: RefUnwindSafe,
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
P: UnwindSafe,
R: UnwindSafe,
Wr: UnwindSafe,
W: UnwindSafe,
I: UnwindSafe,
<P as Parser<I>>::Cli: UnwindSafe,
<R as Runner<W>>::Cli: UnwindSafe,
<Wr as Writer<W>>::Cli: UnwindSafe,
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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, with: F) -> FailOnSkipped<T, F>
fn fail_on_skipped_with<F>(self, with: 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 filtered 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 moreSource§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more