I have a python class MyClass
written in file MyClass.py
:
class MyClass(object):
def __init__(self):
self.myvar = list()
def setvar(self, val):
self.myvar = val
def mymethod(self):
return self.myvar
I have imported in Robot Framework as below:
Library MyClass WITH NAME my_component
I also have a keyword which call a method of objects which are passed to it:
testing component
[Arguments] ${cmp}
log to console ************* ${cmp}
${result} = ${cmp}.mymethod
I have multiple objects instantiated from class MyClass
and every object has different properties. I want to get their attributes using testing component
keyword regardless of the object itself.
When I call testing component
passing my_component
:
Test Method Call
testing component my_component
I get:
No keyword with name '${cmp}.mymethod' found.
If I call it this way in keyword testing component
:
${result} = call method ${cmp} mymethod
I get:
Object 'my_component' does not have method 'mymethod'.
I also tried call method my_component mymethod
for test and I again got Object 'my_component' does not have method 'mymethod'.
.
But when I use ${result} = my_component.mymethod
, everything works fine.
The literal answer to your question of how to call a method of a python object is that you can use extended variable syntax (eg: ${cmp.mymethod()}
or you can use the call method
keyword (eg: call method ${cmp} mymethod
).
For example, normal scalar variables in robot are python string objects. Thus, we can call methods on them such as lower()
and upper()
. The following test case shows how you can call these methods on a string, using the two mechanisms I mentioned earlier:
*** Variables ***
${message} Hello, world # a python string object
*** Test cases ***
Example
# Example using "Call method" keyword
${lower}= call method ${message} lower
should be equal ${lower} hello, world
# Example using extended variable syntax
${upper}= set variable ${message.upper()}
should be equal ${upper} HELLO, WORLD
The problem with your code is your misunderstanding of what my_component
and ${cmp}
represents. They are not python objects. Rather, it is the name of a robot framework library. Even though under the hood it may exist as a reference to an instance of a class defined in the library, from within the test my_component
is simply the name of the library.
This is why my_component.my_method
works - my_component
is the name of a library, and my_method
is the name of a keyword within that library. This is standard robot framework syntax. See Specifying a keyword explicitly in the robot framework user guide.
If you want to be able to pass my_component
around as if it were an object, you can use run keyword
to run the keywords implemented in that library.
For example, start by creating MyClass.py
with the following code:
class MyClass(object):
def mymethod(self):
return "Hello, world"
Your code can work if you replace call method
with run keyword
:
*** Keywords ***
testing component
[Arguments] ${cmp}
log to console ************* ${cmp}
${result} = run keyword ${cmp}.mymethod
Finally, if you really want to pass the actual library object around, you can use the built-in keyword Get Library Instance to get the actual library object, which you can then use with Call Method
*** Keywords ***
testing component
[Arguments] ${cmp_name}
${cmp}= Get library instance ${cmp_name}
log to console ************* ${cmp}
${result} = call method ${cmp} mymethod
[return] ${result}
Oddly, the extended variable syntax doesn't work in this case. I don't know why.