Story writers often find themselves repeating scenarios, or parts thereof, by simply changing some parameter values. These are ideal candidates for using JBehave's parametrisation features. Let's look at the example:
Given a stock of symbol STK1 and a threshold of 10.0 When the stock is traded at 5.0 Then the alert status should be OFF When the stock is traded at 11.0 Then the alert status should be ON
We notice that two lines are repeated and identical but for the values. We can then rewrite this scenario as:
The Examples: keyword signals that the entire scenario is parametrised and should be repeated for as many times as there are data rows in the examples table. At each execution, the named parameters are taken from the corresponding row.
Also it's possible to put the Examples to the story level:
In this case the Examples section in the Lifecycle indicates that the entire story is parametrised and all scenarios should be repeated as many times as there are data rows in the examples table.
It is allowed to use both story level and scenario level Examples at the same time. The story level rows are merged with scenario level ones if present. In case of conflicting keys, the values from the scenario level take precedence. For example, the following story consists of the 4 scenario iterations with different datasets:
One important difference to underline in using table examples is that they require named parameters for the step candidates to be matched to Java methods. The named parameters allow the parameters to be injected using the table row values with the corresponding header name, instead of being extracted from the annotation pattern match. As such, the step annotation pattern must hold the verbatim textual step, e.g.:
Also note that while the characters delimiting the parameter names in the regex pattern are purely conventional - they only serve the purpose of matching the step method in a readable manner - the use of the angle brackets is required as it is used to replace the name with the value in the reporting.
It is also important to note that the same (@Named
-annotated)
methods can match steps that are executed both as standalone or via
examples table, provided that both regex patterns are configured, one as
the main pattern and one as an alias:
Moreover, the examples table alias can happily co-exists with other standalone aliases:
The parameter name delimiters are purely conventional. The step matching works just as well if other delimiters - e.g. [] - are used, provided the patterns are updated accordingly:
The only thing we need to do is to tell the StepCreator to use the custom parameter name delimiters when replacing the parameter value. We do this by configuring a custom instance of ParameterControls:
An alternative way to annotations in specifying the named parameters, is to leverage the name delimiters themselves. Going back to our example:
We can configure JBehave to interpret the name contained between the delimiters as the parameter name and look it up in the parameters provided by the examples table. The default behaviour of parameter lookup is overridden via the ParameterControls:
In this mode, the step method would look much simplified:
Starting from version 4.0, the use of delimiter named parameters is the default behaviour.Another use case of name delimited parameters is to reuse the same step for different parameter values (with different names), e.g.:
Both steps would be matched by the method:
The parameters table can also be loaded from an external resource, be it a classpath resource or a URL.
We need to enable the parser to find the resource with the appropriate resource loader configured via the ExamplesTableFactory: