Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BDD behave Python need to create a World map to hold values

I'm not too familiar with Python but I have setup a BDD framework using Python behave, I now want to create a World map class that holds data and is retrievable throughout all scenarios.

For instance I will have a world class where I can use:

World w 

w.key.add('key', api.response)

In one scenario and in another I can then use:

World w

key = w.key.get('key'). 

Edit:

Or if there is a built in way of using context or similar in behave where the attributes are saved and retrievable throughout all scenarios that would be good.

Like lettuce where you can use world http://lettuce.it/tutorial/simple.html

I've tried this between scenarios but it doesn't seem to be picking it up

class World(dict):
    def __setitem__(self, key, item):
        self.__dict__[key] = item
        print(item)

    def __getitem__(self, key):
        return self.__dict__[key]

Setting the item in one step in scenario A: w.setitem('key', response)

Getting the item in another step in scenario B: w.getitem('key',)

This shows me an error though:

Traceback (most recent call last):
  File "C:\Program Files (x86)\Python\lib\site-packages\behave\model.py", line 1456, in run
    match.run(runner.context)
  File "C:\Program Files (x86)\Python\lib\site-packages\behave\model.py", line 1903, in run
    self.func(context, *args, **kwargs)
  File "steps\get_account.py", line 14, in step_impl
    print(w.__getitem__('appToken'))
  File "C:Project\steps\world.py", line 8, in __getitem__
    return self.__dict__[key]
KeyError: 'key'

It appears that the World does not hold values here between steps that are run.

Edit:

I'm unsure how to use environment.py but can see it has a way of running code before the steps. How can I allow my call to a soap client within environment.py to be called and then pass this to a particular step?

Edit:

I have made the request in environment.py and hardcoded the values, how can I pass variables to environment.py and back?

like image 772
Sam Avatar asked Feb 05 '23 20:02

Sam


2 Answers

It's called "context" in the python-behave jargon. The first argument of your step definition function is an instance of the behave.runner.Context class, in which you can store your world instance. Please see the appropriate part of the tutorial.

like image 81
Szabo Peter Avatar answered Feb 07 '23 18:02

Szabo Peter


Have you tried the simple approach, using global var, for instance:

def before_all(context):
    global response
    response = api.response

def before_scenario(context, scenario):
    global response
    w.key.add('key', response)

Guess feature can be accessed from context, for instance:

def before_feature(context, feature):
    feature.response = api.response

def before_scenario(context, scenario):
    w.key.add('key', context.feature.response)

You are looking for:
Class variable: A variable that is shared by all instances of a class.
Your code in Q uses Class Instance variable.
Read about: python_classes_objects

For instance:

class World(dict):
    __class_var = {}

    def __setitem__(self, key, item):
        World.__class_var[key] = item

    def __getitem__(self, key):
        return World.__class_var[key]

# Scenario A
A = World()
A['key'] = 'test'
print('A[\'key\']=%s' % A['key'] )
del A

# Scenario B
B = World()
print('B[\'key\']=%s' % B['key'] )

Output:

A['key']=test
B['key']=test  

Tested with Python:3.4.2
Come back and Flag your Question as answered if this is working for you or comment why not.

like image 24
stovfl Avatar answered Feb 07 '23 18:02

stovfl