Data Driven
CSV data feeds
Since v1.0.0
CSV data files can be passed into the interpreter to perform feature execution over multiple data sets. The first row in a CSV data file must be a list of column names for the contained data that follows. The values in each record will be bound to attributes in the feature scope having these same names. Feature steps can reference the bound data using these names.
Say you have a users.csv
file containing following user records.
File: data/users.csv
FIRST_NAME,LAST_NAME,JOB
Gwen,Stefani,Pop Singer
Gwyneth,Paltrow,Actress
Gwen,Cooper,Torchwood Agent
The first row in this file specifies a comma separated list of column names. The remaining rows specify the comma separated lists of values for each record. Now say you wanted to submit the details for each user to a web page through a single submit-user.feature
file that accepts all the user data as input one at a time. You can do this in the feature by referencing CSV data values by their column names as follows:
File: features/submit-user.feature
Feature: Submit user ${FIRST_NAME} ${LAST_NAME}
Scenario: submit user details
Given I navigate to the user details page
When I type FIRST_NAME in the first name field
And I type LAST_NAME in the last name field
And I type JOB in the job field
And I click the save button
Then the alert msg should be "User ${FIRST_NAME} saved"
Note: Interpolation of CSV fields ${FIRST_NAME} ${LAST_NAME}
in the feature name and description is supported since v3.12.1
The current CSV record number (starting at 1) is available as an implicit attribute named
data record number
and can be accessed by reference or interpolation.
You can execute this feature for all users in the CSV file by launching Gwen with the -i|--input-data
CLI option.
Examples
- Project
- Standalone
- Yarn
- npm
- pnpm
yarn gwen -b -i gwen/data/users.csv gwen/features/submit-user.feature
or
yarn gwen -b --input-data gwen/data/users.csv gwen/features/submit-user.feature
npm run gwen -- -b -i gwen/data/users.csv gwen/features/submit-user.feature
or
npm run gwen -- -b --input-data gwen/data/users.csv gwen/features/submit-user.feature
pnpm gwen -b -i gwen/data/users.csv gwen/features/submit-user.feature
or
pnpm gwen -b --input-data gwen/data/users.csv gwen/features/submit-user.feature
gwen -b -i data/users.csv features/submit-user.feature
or
gwen -b --input-data data/users.csv features/submit-user.feature
Gwen will read in the CSV file, and for each record will:
- Bind the data to the feature
- And execute the feature
A feature detail report will be generated for each data record. If you specify the --parallel
CLI option, the feature will execute all records in parallel.
@Examples annotation
Since v2.10.0
Consider the following scenario outline with an examples table
Scenario outline with inlined data
Scenario Outline: I load items from CSV files
When I add a <Status> "<Item>" item
Examples:
| Item | Status |
| Walk the dog | pending |
| Get the milk | done |
| Feed the cat | pending |
The data table in the examples clause can be externalised to a CSV file and imported using the @Examples
annotation as follows:
CSV File: data/items.csv
Item,Status
Walk the dog,pending
Get the milk,done
Take out trash,pending
Scenario outline with externalised data
@Examples("data/items.csv")
Scenario Outline: I load items from CSV files
When I add a <Status> "<Item>" item
This will resolve to an identical outline when expanded at runtime:
Scenario Outline: I load items from CSV files
When I add a <Status> "<Item>" item
Examples: Data file: data/items.csv
| Item | Status |
| Walk the dog | pending |
| Get the milk | done |
| Feed the cat | pending |
Where filter
Since v3.27.0
The data can also be filtered using a where
JavaScript expression filter. For example, to get all the records where the data in the Status
column matches pending
:
Scenario outline with externalised and filtered data
@Examples(file="data/items.csv",where="'${Status}'=='pending'")
Scenario Outline: I load items from CSV files
When I add a <Status> "<Item>" item
Will resolve to the following containing pending
Status records only:
Scenario Outline: I load items from CSV files
When I add a <Status> "<Item>" item
Examples: Data file: data/items.csv, where: '${Status}'=='pending'
| Item | Status |
| Walk the dog | pending |
| Feed the cat | pending |
String interpolation syntax can also be used to reference a value in the CSV record or current scope. For example, to get all the records where the Status
column matches the value bound to an in-memory attribute named SelectedStatus
:
Scenario outline with externalised and filtered data
@Examples(file="data/items.csv",where="'${Status}'=='${SelectedStatus}'")
Scenario Outline: I load items from CSV files
When I add a <Status> "<Item>" item
Name prefix
Since v3.27.0
A prefix="string"
attribute can be added to prepend a prefix to each column name in the CSV heaader record. This is useful for avoiding any potential name clashes with existing data in the current scope.
Scenario outline sourced from CSV file having column names Status, Item
@Examples(file="data/items.csv",prefix="todo.",where="'${todo.Status}'=='pending'")
Scenario Outline: I load items from CSV files
When I add a <todo.Status> "<todo.Item>" item
Will result in the column names todo.Status, todo.Item
when todo.
prefix is applied at runtime
Scenario Outline: I load items from CSV files
When I add a <todo.Status> "<todo.Item>" item
Examples: Data file: data/items.csv, prefix: todo., where: '${todo.Status}'=='pending'
| todo.Item | todo.Status |
| Walk the dog | pending |
| Feed the cat | pending |
Required flag
Since v3.20.0
A required=true
attribute can be added to raise an error if no data is returned by the where
clause filter.
Scenario outline which raises an error if externalised and filtered data is empty
@Examples(file="data/items.csv",where="'${Status}'=='${SelectedStatus}'",required=true)
Scenario Outline: I load items from CSV files
When I add a <Status> "<Item>" item