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.
Enter the argument to be used with the keyword. Go back to your test case. Now, you need to pass the value which is the URL to be used for the test case. In the test case, when you type the user-defined keyword and press Ctrl + Spacebar, it gives the details of the keyword along with the arguments.
The first thing to do, to achieve this is to create a folder in the root of the project we have i.e. lib. Next thing is to create a file for our custom library which we will be used to write our own custom keyword which can be imported into our Robot Framework file.
To pass a dictionary to a keyword, you do it like any other argument. In your case, if you have a dictionary named ${Participants} , you would pass it as ${Participants} . As for iterating over the dictionary, you need to replace $ with @ , and use FOR/IN.
The first is to create a new keyword that calls all the other keywords, and then call that from Run keyword if . This might be the most readable solution, but at the expense of having to write and document another keyword. Save this answer. Show activity on this post.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With