Matching Step Expression¶
To match gherkin steps into python code, we used a pattern matcher.
The default pattern matcher is based on curly brace to discover variable, and it match a single world.
But if it is enclosed by "
, then it can be a sentence (that can’t contains "
at the moment, there is no way to escape it).
matcher |
Python decorator example |
Gherkin usage example |
---|---|---|
{username}
|
@given('a user {username}')
|
Given a user Alice
|
"{username}"
|
@then('I see the text "{expected}"')
|
I see the text "Welcome Alice"
|
Typing support¶
The default matcher does not enforce the type in the text of the decorator, it use the function signature.
Supported types are: bool
, date
, datetime
, float
, int
, str
, Enum
and Literal[...]
:
boolean¶
Python signature:
@given('Given the feature flag "{feature_flag}" is set to {ff_toggle}')
def toggle_feature_flag(feature_flag: str, ff_toggle: bool):
...
Gherkin example:
Given the feature flag "DARK_MODE" is set to true
Then the system status should be off
Note
True values are
true
,1
,yes
,on
False values are
false
,0
,no
,off
Those values are case insensitive.
Everything else will raise a value error.
date¶
Python signature:
@given("the user's subscription expires on {expires_on}")
def given_expires_on_subscription(expires_on: date):
...
Gherkin example:
Given the user's subscription expires on 2025-12-31
datetime¶
Python signature:
@given("the user's subscription expires at {expires_at}")
def given_expires_at_subscription(expires_at: date):
...
Gherkin example:
Given the user's subscription expires at 2025-12-31T08:00:00Z
float¶
Python signature:
@given("the account balance is {account_balance}")
def toggle_feature_flag(account_balance: float):
...
Gherkin example:
Given the account balance is 99.99
int¶
Python signature:
@then("the cart should contain {items_count} items")
def assert_cart_items_count(feature_flag: int):
...
Gherkin example:
Then the cart should contain 3 items
str¶
Python signature:
@given('Given the user role {role} protected by passphrase "{passphrase}"')
def given_role(role: str, passphrase: str):
...
Gherkin example:
Given the user role admin protected by passphrase "I am feeling lucky"
Enum¶
Python signature:
from enum import Enum
class OrderStatus(Enum):
PENDING = "Pending"
PROCESSING = "Processing"
CANCELLED = "Cancelled"
REFUNDED = "Refunded"
COMPLETED = "Completed"
@given("Given the order status is {order_status}")
def toggle_feature_flag(order_status: OrderSatus):
...
Gherkin example:
Given the order status is PROCESSING
Note
For enum, the key must be passed, not the value.
Literal¶
Python signature:
from typing import Literal
FeatureFlagName = Literal["dark_mode", "light_mode", "beta_feature"]
@given("the feature flag {feature} is set to {status}")
def set_feature_flag(feature: FeatureFlagName, status: bool):
...
Gherkin example:
Given the feature flag dark_mode is set to on
Complex types and more about Gherkin¶
To provide long text or data set, gherkin supports 2 things, doc strings, and data tables.
It allow to multiline step, and we will start with the docstring for json support.
Json¶
@given("the user provides the following profile data:")
def create_user_from_json(doc_string: dict[str, Any]):
...
Given the user provides the following profile data:
"""json
{
"username": "johndoe",
"email": "johndoe@example.com",
"address": {
"street": "123 Main St",
"city": "Anytown",
"postal_code": "12345"
}
}
"""
Note
When a media type is set to json
("""json
in gherkin docstring)
then tursu will parse the json and return it as a list or a dict.
Otherwise, a plain string will be returned.
List of dict from a data table¶
@given("the user provides the following login credentials:")
def fill_user_table(data_table: list[dict[str, str]]):
...
Given the user provides the following login credentials:
| username | password |
| johndoe | secret123 |
| janedoe | password1 |
Note
data_table looks like
[
{"username": "johndoe", "password": "secret123"},
{"username": "janedoe", "password": "password1"},
]