How are Behave decorators created / declared?
I am currently using Behave (BDD for Python) and digging through the source code to understand how decoders are declared @given
, @when
and @then
.
The most I've gone away is to see step_registry.py
where I found the function setup_step_decorators(context=None, registry=registry)
that appears to be doing the job.
However, I don't quite understand how these decorators are created, since they are not explicitly specified in the source code in the form def when(...):
. I am under the impression that they are declared based on a list of strings ( for step_type in ('given', 'when', 'then', 'step'):
), which is then processed by the call make_decorator()
.
Can anyone walk through the code and explain where / how these decorators are declared ?
You can access the source code for Behave here .
source to share
Well, let's start from the outside:
if context is None:
context = globals()
for step_type in ('given', 'when', 'then', 'step'):
step_decorator = registry.make_decorator(step_type)
context[step_type.title()] = context[step_type] = step_decorator
I think the last line is confusing you.
Each global module namespace is just a dictionary. The function globals()
returns this dictionary. If you modify this dictionary, you are creating global global modules. For example:
>>> globals()['a'] = 2
>>> a
2
In this case, by default context = globals()
. So, for, say, the first one step_type
, you effectively do this:
>>> globals()['given'] = step_decorator
source to share
They are put in globals()
around line 90 (at this point context
there is globals()
because there context
is None
):
# -- Create the decorators
def setup_step_decorators(context=None, registry=registry):
if context is None:
context = globals()
for step_type in ('given', 'when', 'then', 'step'):
step_decorator = registry.make_decorator(step_type)
context[step_type.title()] = context[step_type] = step_decorator
You can do this too ( globals()
works just like a regular dictionary):
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> globals()['a'] = 5
>>> a
5
source to share