Reputation: 6961
Using the Robot Framework Documentation on Variable Files as a guide I implemented a Variable File Class with the get_variables. The basic example works as described.
When I implement a triple nested Dictionary (${A.B.C}
) I can access the first two using ${A}
and ${A.B}
notation. However, when I want to access the third node ${A.B.C}
the result is that I get an error
Resolving variable '${A.B.C}' failed: AttributeError: 'OrderedDict' object
has no attribute 'C'
In the below three examples I have an RF generated nested dictionary that I can access all nodes through the dot notation. The second example is a plain Python dictionary that is given back by the Variable Class. In the last example the Variable class returned is of the type OrderedDict
.
Although the ${A['B']['C']['key']}
works, it is more difficult to read in the code. When I load a similar yaml structure it supports the dot notation fully but this is not an option as the yaml file is static, and I require flexibility of Python for some of the key values.
So, I'm looking for some support on how to return a data structure that allows Robot Framework to interpret the full nested structure with the dot notation.
Variable Class File
from collections import OrderedDict
class OrderDict(object):
def get_variables(self):
C = OrderedDict([(u'key', u'value')])
B = OrderedDict([(u'C', C)])
A = OrderedDict([(u'B', B)])
D = {
u'E':
{
u'F':
{
u'key': u'value'
}
}
}
return OrderedDict([(u'DICT__A', A), (u'DICT__D', D)])
Robot Framework Script
*** Test Cases ***
Dictionary RF
${Z} Create Dictionary key=value
${Y} Create Dictionary Z=${Z}
${X} Create Dictionary Y=${Y}
Log To Console ${EMPTY}
Log To Console ${X}
Log To Console ${X['Y']['Z']['key']}
Log To Console ${X.Y}
Log To Console ${X.Y.Z}
Log To Console ${X.Y.Z.key}
Plain Dictionary Variable Class
Log To Console ${EMPTY}
Log To Console ${D}
Log To Console ${D['E']['F']['key']}
Log To Console ${D.E}
Log To Console ${D.E.F}
Log To Console ${D.E.F.key}
Ordered Dictionary Variable Class
Log To Console ${EMPTY}
Log To Console ${A}
Log To Console ${A['B']['C']['key']}
Log To Console ${A.B}
Log To Console ${A.B.C}
Log To Console ${A.B.C.key}
Robot Framework Console Log
Suite Executor: Robot Framework 3.0.2 (Python 2.7.9 on win32)
Dictionary RF
{u'Y': {u'Z': {u'key': u'value'}}}
value
{u'Z': {u'key': u'value'}}
{u'key': u'value'}
value
| PASS |
------------------------------------------------------------------------------
Plain Dictionary Variable Class
{u'E': {u'F': {u'key': u'value'}}}
value
{u'F': {u'key': u'value'}}
| FAIL |
Resolving variable '${D.E.F}' failed: AttributeError: 'dict' object has no attribute 'F'
------------------------------------------------------------------------------
Ordered Dictionary Variable Class
{u'B': OrderedDict([(u'C', OrderedDict([(u'key', u'value')]))])}
value
OrderedDict([(u'C', OrderedDict([(u'key', u'value')]))])
| FAIL |
Resolving variable '${A.B.C}' failed: AttributeError: 'OrderedDict' object has no
attribute 'C'
Upvotes: 1
Views: 3757
Reputation: 6961
In the Robot Framework Slack channel Pekka Klarck pointed out that Robot Framework internally uses the robot.utils.DotDic
class. Having get_variables()
return a DotDic
structure resolved my issue and I can now use the dot notation. Below is the code for the Variable Class DotDic (stored as DotDic.py
).
from robot.utils import DotDict
class DotDic(object):
def get_variables(self):
G = {
u'H':
{
u'I':
{
u'key': u'value'
}
}
}
return {u'G': self.dict_to_dotdict(G)}
def dict_to_dotdict(self, dct):
dd = DotDict({})
for key, val in dct.items():
if isinstance(val, dict):
dd[key] = self.dict_to_dotdict(val)
else:
dd[key] = val
return dd
Upvotes: 1