Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
In addition to standard Gherkin features, Gwen also supports and introduces meta features. These are also defined in Gherkin and can provide powerful capabilities for eliminating redundancy. They also provide a clean separation between evaluation and configuration. Meta features are loaded into the interpreter on startup and can be used to initialise and configure the environment context for engines at load time.
Composable Step Definitions
Composable step definitions allow you to declaratively compose custom steps in terms of other steps to create what are effectively callable procedures that can optionally accept parameters. They are declared exactly like scenarios but are annotated with the
@StepDef tag and bind a sequence of steps to an expression that serves as the callable name. StepDefs can be defined in both standard features and meta features and are cached in the interpreter when loaded. They must be declared before any scenarios that use them, and are evaluated only when referenced by name in those scenarios or other StepDefs at runtime.
StepDefs and Meta
Composable step definitions and meta features are powerful capabilities that are unique to Gwen. It is a good idea to always define step definitions in meta files so that..
- They do not clutter features
- They can be reused across many features
- They are maintained in one place
- They separate configuration from specification
StepDefs with Parameters
Parameters can be declared in StepDefs using the
<name> syntax and dereferenced with
Feature: Google meta @StepDef Scenario: I do a google search for "<query>" This is a custom step definition that accepts a query string as input and performs a google search on it and checks for a returned match. It is not immediately executed but rather loaded into memory and executed only when referenced in another step by name. Given I navigate to "http://www.google.com" And the search field can be located by name "q" When I enter "$<query>" in the search field Then the page title should start with "$<query>" And the first match can be located by class name "r" And the first result can be located by tag name "a" in the first match
You can then use this step definition in any other feature to perform a google search.
Feature: Google feature Scenario: Perform a google search This scenario calls the a step definition defined in the Goolge.meta file to perform a google search for "gwen-web". It then clicks the first link in the returned results and checks the title and URL of the page that is loaded. Given I do a google search for "gwen-web" When I click the first result Then the page title should contain "gwen-interpreter/gwen-web" And the current URL should be "https://github.com/gwen-interpreter/gwen-web"
If the meta and feature files are in the same directory, then Gwen will auto discover the meta. You can then launch the feature to perform the google search as follows (assuming you have Gwen-web installed and the
bin directory is in your system path):
If the meta resides in a different directory, then you can use the
--meta option to specify its location.
gwen features/GoogleSearch.feature -m other-dir/Google.meta gwen features/GoogleSearch --meta other-dir/Google.meta
If you have the meta and feature files in a directory structure such as the following and invoke Gwen on the top level directory, then it will find and execute the feature and also auto-discover the meta (since it exists in the path to the feature file). In this case, you don't have to specify the
top-dir top-dir/Google.meta top-dir/features/GoogleSearch.feature
With the above file structure, Gwen will find the feature and auto discover the meta if you launch it on the top level directory.
You can also explicitly import meta files into your feature files. This is useful for cases where you have many meta files and it is not practical to load all of them for every feature file. It is also useful for cases where the auto-meta-discovery and
-m command line mechanisms are insufficient for controlling exactly what meta you want to load.
You can manage and control exactly what meta will be loaded by your features without ever having to specify it on the command line. This can help avoid redundant meta loads and also greatly improve performance and usability when you have a lot of meta spread across many files.
For example, say you have 10 meta files in a directory and you only want to load one of them when executing a feature. Previously, you could do this through the
-m command line switch as follows:
gwen -m metadir/module1.meta test.feature
You could also load all 10 meta files as follows:
gwen -m metadir test.feature
Remembering exactly which meta to load for which features is impractical, and blindly loading all meta files to execute a feature that only uses one or some of them is wasteful.
With meta imports, we can do away with having to use the
-m option altogether by adding the following annotation to the
Feature declaration in each feature file. For example, we can declare what meta the
test.feature file should load by specifying an import annotation in the feature file itself as follows:
@Import("metadir/module1.meta") Feature: test feature Scenario: scenario 1 Given I want .. ..
Now we can simply just specify the feature on the command line as follows:
Gwen will then load the meta file specified in the import before executing the steps in the feature.
You can add any number of meta imports to a feature. The following imports two meta files.
@Import("metadir/module1.meta") @Import("metadir/module2.meta") Feature: test feature Scenario: scenario 1 Given I want .. ..
You can also chain (or string together) meta imports across meta files. For example, if the
module2.meta always requires
module1.meta, then you can import the latter into the former:
@Import("metadir/module1.meta") Feature: module 2 meta @StepDef Scenario: .. Given I want .. ..
Now any feature that imports
module2.meta will also implicitly import
module1.meta. For example, if we declare
test.feature to import
module2.meta as follows:
@Import("metadir/module2.meta") Feature: test feature Scenario: scenario 1 Given I want .. ..
module2.meta will be loaded (in that order) when the feature is executed without you having to specify any meta on the command line:
The path to the meta file in all import annotations is relative to the working directory where Gwen is invoked.
If a recursive (or cyclic) import is detected in an import chain, Gwen will report it by throwing an exception with a message specifying which import annotation was the culprit and the file it was declared in.
Meta imports are always loaded before any auto discovered meta files or
-m command line meta files are loaded, and therefore have the least precedence so their contents can be shadowed.