Meta Specs
Meta specs are Gherkin specifications that describe how steps in features will execute and are the automation glue in Gwen. They define all the step definitions and bindings required for automation and attach to features at runtime.
StepDefs
Composable step definitions
Step definitions are defined as @StepDef
annotated Scenarios with names that map to steps in features and bodies that call out to DSL steps to perform operations.
Put all your step definitions in meta to keep your features clean and free of automation concerns.
Consider the following feature step:
File: features/todo.feature
Given a new todo list
A step definition for executing this step could be defined in meta as follows:
File: features/todo.meta
@Context
@StepDef
Scenario: a new todo list
Given my todo list can be located by css ".todo-list"
When I navigate to "${todo.page.url}"
Then the page title should contain "TodoMVC"
And my todo list should be empty
Calls DSL steps:
Notice how the name of the StepDef matches the name of the feature step (excluding the leading Given keyword). This is how step definitions bind to feature steps in Gwen; by name. Notice also that the body calls out to several DSL steps to perform the desired operations. Composing StepDefs in this manner is all you need to do to make your features executable.
StepDefs with parameters
StepDefs can also be declared to accept parameters using one or more <param-name>
placeholders in the declared name as follows:
Then the list will contain 2 items
@Assertion
@StepDef
Scenario: the list will contain <expected-count> items
Given the item count can be located by css ".todo-count"
Then the item count should contain "$<expected-count>"
Calls DSL steps:
Here the name of the StepDef matches the name of the step in the feature when the value 2
(in the feature step) is substituted in place of <expected-count>
in the StepDef name. This is how parameters are passed to StepDefs in Gwen; by substitution. The last step in the body utilises the parameter value as $<expected-count>
.
Synchronized StepDefs
In the rare case where you might need to synchronize the execution of your StepDef to a single thread (due to resource contention or a conflict for example), you can do so by tagging it with the @Synchronized
annotation. Gwen will then guarantee that only one thread will execute your StepDef at any given time when multiple features or scenarios are executed in parallel mode by concurrent threads.
Meta Load Strategies
Associative Strategy
Since v2.40.0
A meta and feature file are considered to be associated with each other if the two files are in the same directory and have the same names (excluding their file extensions). The associative strategy will, for every feature:
- Load the meta file with a matching file name if it exists in the same directory as the feature
- Execute the feature
Associative meta is the default and always active strategy since Gwen 4.
If you have your meta and feature files in a directory structure as follows:
/features
├── todo.meta
├── todo.feature
├── /dir1
│ ├── todo1.meta
│ ├── todo1.feature
│ └── todo1a.feature
└── /dir2
├── todo2.meta
├── todo2.feature
└── /dir3
└── todo3.feature
When you launch Gwen to execute on the features
directory, the associative strategy will:
- Load the
todo.meta
and execute thetodo.feature
- Load the
todo1.meta
and execute thetodo1.feature
- Load no associative meta and execute the
todo1a.feature
- Load
todo2.meta
and execute thetodo2.feature
- Load no associative meta and execute the
todo3.feature
When you launch Gwen to execute on the features/dir1
directory, the associative strategy will:
- Load the
todo1.meta
and execute thetodo1.feature
- Load no associative meta and execute the
todo1a.feature
When you launch Gwen to execute the features/dir2/todo2.feature
file, the associative strategy will:
- Load no associative meta and execute the
todo2.feature
Common Strategy
Since v1.0.0
The common strategy enables you to manage common and reusable meta files (in addition to associateve meta) in a directory other than your features directory. How you name your meta files or manage your meta directory structure does not matter.
- Yarn
- npm
- pnpm
To load a single meta file from a meta
directory (for example), use the -m|meta
launch option and specify the path to the meta file:
yarn gwen -m meta/common.meta
To recursively load all meta files in the meta
directory:
yarn gwen gwen/features -m meta
To load a single meta file from a meta
directory (for example), use the -m|meta
launch option and specify the path to the meta file:
npm run gwen -- -m meta/common.meta
To recursively load all meta files in the meta
directory:
npm run gwen -- gwen/features -m meta
To load a single meta file from a meta
directory (for example), use the -m|meta
launch option and specify the path to the meta file:
pnpm gwen -m meta/common.meta
To recursively load all meta files in the meta
directory:
pnpm gwen gwen/features -m meta
Import Strategy
Since v1.9.0
The import strategy enables you to selectively import one or more meta files for any given feature file so they will load automatically without you having to specify their locations using the -m|meta
launch option on every launch. This is useful for cases where you have many reusable meta files and it is not practical to load all of them for every feature file.
The import strategy can be used to avoid redundant meta loads and improve performance and scalability in extreme cases where all your common meta combined exceeds or approaches 500 KB in size (that is: when you have LOTS of common meta).
For example, say you have your common meta files in one directory and your feature files in another directory as follows:
/meta
├── module-1.meta
├── module-2.meta
├── module-3.meta
│ ..
├── module-n.meta
├── /dir1
│ ├── submodule-1.meta
│ ├── submodule-2.meta
│ ├── submodule-3.meta
│ │ ..
│ └── submodule-n.meta
│
/features
├── spec-1.feature
├── spec-2.feature
├── spec-3.feature
│ ..
└── spec-n.feature
- Yarn
- npm
- pnpm
To load only one meta file for one feature file using the common meta strategy, you would have to explicitly specify which one using the -m|meta
CLI option as follows:
yarn gwen -m gwen/meta/module-1.meta gwen/features/spec-1.feature
To load only one meta file for one feature file using the common meta strategy, you would have to explicitly specify which one using the -m|meta
CLI option as follows:
npm run gwen -- -m gwen/meta/module-1.meta gwen/features/spec-1.feature
To load only one meta file for one feature file using the common meta strategy, you would have to explicitly specify which one using the -m|meta
CLI option as follows:
pnpm gwen -m gwen/meta/module-1.meta gwen/features/spec-1.feature
Having to remember exactly which meta to load for which features is inconvenient and blindly loading all meta files to execute a feature that only requires one or some of them is wasteful.
With associative meta enabled, you can do away with having to explicitly specify any meta files on CLI calls to Gwen by creating an associative meta file for each feature file and specifying the required meta to import in each.
Although it's possible to specify imports directly in feature files, we do not recommend you doing so since it would introduce automation concerns into your features. Confining imports to associative meta instead will keep your features clean and untouched.
For example, you could import the module-1.meta
into a new (or existing) associative meta file for spec-1.feature
as follows:
File: features/spec-1.meta
@Import("meta/module-1.meta")
Feature: Associative spec 1 meta
Or using relative path since v4.0.0
@Import("../meta/module-1.meta")
Feature: Associative spec 1 meta
Note that this associative meta specification contains nothing except one import annotation followed by a feature declaration and name. It contains nothing else since it serves only to import one meta file. It would sit alongside your unchanged feature file on the file system as follows:
/features
├── spec-1.feature
├── spec-1.meta
│ ..
/meta
├── module-1.meta
| ..
- Yarn
- npm
- pnpm
With the import in place, you could then invoke Gwen to execute the feature without having to explicitly specify the meta file in the CLI call:
yarn gwen gwen/features/spec-1.feature
With the import in place, you could then invoke Gwen to execute the feature without having to explicitly specify the meta file in the CLI call:
npm run gwen -- gwen/features/spec-1.feature
With the import in place, you could then invoke Gwen to execute the feature without having to explicitly specify the meta file in the CLI call:
pnpm gwen gwen/features/spec-1.feature
Gwen would then load the associative meta which in turn would load the imported meta before proceeding to execute the feature.
You can add any number of meta imports to a file. The following example imports two meta files for spec 2:
File: features/spec-2.meta
@Import("meta/module-1.meta")
@Import("meta/module-2.meta")
Feature: Associative spec 2 meta
You can also chain or link imports together. For example, if you wanted module-2.meta
to load whenever module-3.meta
is loaded, you could import the former into the latter as follows:
File: meta/module-3.meta
@Import("meta/module-2.meta")
Feature: meta 3
@StepDef
Scenario: ..
Given ..
When ..
Then ..
..
Now any import of module-3.meta
will also import module-2.meta
.
File: features/spec-3.meta
@Import("meta/module-3.meta")
Feature: Associative spec 3 meta
- Yarn
- npm
- pnpm
In this example, the module-2.meta
and module-3.meta
files will be loaded (in that order) before test-3.feature
is executed. Again, this would happen without you having to specify any meta in the CLI call to Gwen.
yarn gwen features/spec-3.feature
In this example, the module-2.meta
and module-3.meta
files will be loaded (in that order) before test-3.feature
is executed. Again, this would happen without you having to specify any meta in the CLI call to Gwen.
npm run gwen -- gwen/features/spec-3.feature
In this example, the module-2.meta
and module-3.meta
files will be loaded (in that order) before test-3.feature
is executed. Again, this would happen without you having to specify any meta in the CLI call to Gwen.
pnpm gwen gwen/features/spec-3.feature
The path to the meta file in all imports can be absolute or relative. If a recursive (or cyclic) import is detected in any import chain, Gwen will report it by throwing an exception with a message identifying the offending import and the file it was declared in.
Meta files loaded through the import strategy get last precedence and therefore can be overridden by meta files loaded through any other meta load strategy.