Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass objects to keywords in robot framework?

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.

like image 805
Sara Sarvi Avatar asked Oct 25 '16 10:10

Sara Sarvi


People also ask

How do you call a keyword in Robot Framework?

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.

How do I create a custom keyword in Robot Framework?

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.

How do you pass a dictionary argument in Robot Framework?

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.

How do I run multiple keywords in Robot Framework?

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.


1 Answers

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.

like image 126
Bryan Oakley Avatar answered Oct 24 '22 19:10

Bryan Oakley