Data Types in Steps
Every value captured from a Gherkin step arrives at the step function as a plain string, no matter how it looks in the feature file. If a step talks about numbers, dates, or booleans, the step definition is responsible for converting the string into the right Python type before it is stored on the context or used in an assertion.
Converting Numeric Parameters
from behave import given, then
@given("I deposit {amount} into the account")
def step_impl(context, amount):
# amount is the string "50.50" here
context.balance = context.balance + float(amount)
@then("the account shows {amount}")
def step_impl(context, amount):
assert context.balance == float(amount)
Handling Booleans and Flags
Gherkin has no boolean literals. Steps that take on/off style words need a small mapping, and an unknown word should fail fast with a clear message:
from behave import step
FLAGS = {"enabled": True, "disabled": False}
@step("the maintenance mode is {state}")
def step_impl(context, state):
if state not in FLAGS:
raise AssertionError(f"unknown state {state!r}")
context.maintenance = FLAGS[state]
Table Cells Are Strings Too
The same rule applies to tables. Each cell you read from context.table is a string, so numeric columns must be converted when the table is consumed:
from behave import given
@given("the product list is ready:")
def step_impl(context):
context.products = [
{"sku": row["sku"],
"price": float(row["price"]),
"stock": int(row["stock"])}
for row in context.table
]
Validating Free-Form Values
For values with a format (dates, IDs, emails), parse and validate inside the step and raise an assertion error that shows the offending text. A failing conversion message like cannot parse date '2026-13-01' is far more useful than a cryptic type error three steps later.
Summary
Never trust the literal type in a feature file. Capture strings, convert with int(), float(), or an explicit mapping, validate unknown values with a clear error message, and only then store the value on the context.