How to access methods from object after it is saved in a variable

I have created a Python library with a method that returns the object self. I saved this object into a robot variable. But I am unable to access the method present in this object by using syntax ${var}.method_name or ${var.name}

Python library:

class sing():
    def __init__(self):
        pass
    def init(self):
        return self
    def name(self):
        return "hi"

Robot code:

Test
   ${val}=  Init
   Log To Console  \n${val}
   ${word}=  Run Keyword  ${val}.name
   Log To Console  ${word}

Result:

==============================================================================
Test                                                                  .
<sing.sing object at 0x7ffff06584e0>
Test                                                                  | FAIL |
No keyword with name '<sing.sing object at 0x7ffff06584e0>.name' found.
------------------------------------------------------------------------------

Trying to access as ${var.name}

Test
   ${val}=  Init
   Log To Console  \n${val}
   ${word}=  Run Keyword  ${val.name}
   Log To Console  ${word}

Result:

Test                                                                  .
<sing.sing object at 0x7ffff0658d30>
Test                                                                  | FAIL |
Keyword name must be a string.

Hi Anusha,

You were nearly there, change this line

   ${word}=  Run Keyword  ${val.name}

to

   ${word}=  Set Variable  ${val.name()}

Dave.

FYI - here’s a full working example:

sing.py

class sing():
    def __init__(self):
        pass
    def init(self):
        return self
    def name(self):
        return "hi"

Anusha.robot

*** Settings ***
Library		sing.py

*** Test Cases ***
Test
   ${val}=  Init
   Log To Console  \n${val}
   ${word}=  Set Variable  ${val.name()}
   Log To Console  ${word}

Console Log:

$ robot Anusha.robot 
==============================================================================
Anusha                                                                        
==============================================================================
Test                                                                  .
<sing.sing object at 0x7f887b0e5000>
..hi
Test                                                                  | PASS |
------------------------------------------------------------------------------
Anusha                                                                | PASS |
1 test, 1 passed, 0 failed
==============================================================================
Output:  /home/dave/Documents/tmp/Anusha/output.xml
Log:     /home/dave/Documents/tmp/Anusha/log.html
Report:  /home/dave/Documents/tmp/Anusha/report.html

HTML Log:

1 Like

Works like a charm… Thank you so much…

2 Likes

Notice that simply using

*** Settings ***
Library		sing.py

*** Test Cases ***
Test
   ${word}=    Name
   Log To Console    ${word}

ought to work the same way. Unless you have some specific reason for your approach, this is a lot simpler.

2 Likes

I don’t get the same behaviour when I execute the below code. I get Keyword name cannot be empty error. I basically want to execute any method from the obj stored in variable val.

*** Settings ***
Library         sing.py

*** Test Cases ***
Test
   ${val}=  Init
   Log To Console  \n${val}
   ${word}=  ${val.name()}
   Log To Console  ${word}

Thanks… I have a python file that returns more than 1 object at a time. So I’m finding ways to save the returned object into a variable in robot and then call the methods in that object.

Can someone please help me with this code?

*** Settings ***

Library sing.py

*** Test Cases ***
Test
${val}= Init
Log To Console \n${val}
${word}= ${val.name()}
Log To Console ${word}

Hi Anusha,

It’s usually a good idea to show all the relevant code as well as any error messages when asking for help, but I’ll try.

Q1. is sing.py still the same?
Q2. does the name() function in sing.py still return “hi”?

Q3. Assuming the answer to Q2 is yes, then do you have a keyword called hi somewhere ?

If the answer to Q3 is No, then your problem is probably in this line:

${word}=    ${val.name()}

And you probably got a message something about not being able to find a keyword called “Hi”

That’s my best guess,

Dave.

Here is my code:

cat sing.py
#!/usr/bin/env python

class sing():
def __init__(self):
    pass
def init(self):
    return self
def name(self):
    return "hi"

cat anusha.robot

*** Settings ***
Library         sing.py

*** Test Cases ***
Test
   ${val}=  Init
   Log To Console  \n${val}
   ${word}=  ${val.name()}
   Log To Console  ${word}

So I am trying to execute method - name from the object ${val} so that the variable ${word} gets the value “hi”.

The error that I see when I execute anusha.robot is “Keyword name cannot be empty.”

bash-4.2$ python -m robot anusha.robot 
==============================================================================
Anusha                                                                        
==============================================================================
Test                                                                  .
<sing.sing object at 0x7ffff0658cc0>
Test                                                                  | FAIL |
Keyword name cannot be empty.
------------------------------------------------------------------------------

Hi Anusha,

Keyword name cannot be empty. Ah ok, I guess that makes sense, because the keyword hi doesn’t exist there’s no value to assign to to ${word}, In my example from a while back I used the keyword Set Variable to set the value of ${word} to hi.

Robot Framework evaluates ${val.name()} first and then tries to process the line with robot interpreter so this:

${word}=  ${val.name()}

is the same to robot framework as this:

${word}= hi

The python function call (val.name()) is processed first → it’s value (hi) is passed into the variable ${val.name()} → then robot framework tries to work out what to do with ${word}= hi, and obviously this is not valid.

The question is what were you wanting it to do? what was the reason to remove Set Variable?

Dave.

My primary intention is to be able to run the object methods. The methods themselves may or may not return any value. . For example like this:

bash-4.2$ cat sing.py 
#!/usr/bin/env python

class sing():
    def __init__(self):
        pass
    def init(self):
        return self
    def name(self):
        print("hi")
bash-4.2$ cat anusha.robot 
*** Settings ***
Library         sing.py

*** Test Cases ***
Test
   ${val}=  Init
   Log To Console  \n${val}
   ${val.name()}

But I get the same error Keyword name cannot be empty.
I understand why this behaves so. Can you please provide me a solution for my code to work ie being able to run keywords from the object created.

Hi Anusha,

Pekka (@pekkaklarck) already did that, see his post:

Dave.

I do not want to import it right at the beginning. I want the object to get initialised only on certain conditions and will need multiple instances of the class sing().

Hi Anusha,

Consider the example below where the python file does nothing until one of it’s functions are called. You can do something like this, there’s no need to have an __init__ function in your py file (it’'s optional), but if you have a some initialisation that needs to happen before the other keyword functions, just put it in a normal function and call it as a keyword before the keyword that needs it inside your if statement.

Dave.

singa.py

class singa():
    def Sound_Music(self):
        return "Doe a Deer"
    def Song_ABBA(self):
        return "I am the Dancing Queen"

singb.py

class singb():
    def DanceA(self):
        return "Bharatanatyam"

    def DanceB(self):
        return "Kathakali"

    def DanceC(self):
        return "Kathak"

    def DanceD(self):
        return "Kuchipudi"

    def DanceE(self):
        return "Odissi"

    def DanceF(self):
        return "Sattriya"

    def DanceG(self):
        return "Manipuri"

    def DanceH(self):
        return "Mohiniyattam"

singc.py

class singc():
    def Song_CA(self):
        return "brrrr"
    def Song_CB(self):
        return "pt pt pt pt"
    def Song_CE(self):
        return "whrrrrr"

Anusha2.robot

*** Settings ***

Library		singa.py
Library		singb.py
Library		singc.py

*** Test Cases ***
Test
   ${condion}= 	Evaluate 	random.randint(0, 13)
   IF 	${condion} == 0
   	${word}=  Sound Music
	   Log To Console  ${word}
	 END
	 IF 	${condion} == 1
   	${word}=  Song Abba
	   Log To Console  ${word}
	 END
	 IF 	${condion} == 2
   	${word}=  Dancea
	   Log To Console  ${word}
	 END
	 IF 	${condion} == 3
   	${word}=  Danceb
	   Log To Console  ${word}
	 END
	 IF 	${condion} == 4
   	${word}=  Dancec
	   Log To Console  ${word}
	 END
	 IF 	${condion} == 5
	 ${word}=  Danced
	   Log To Console  ${word}
	 END
	 IF 	${condion} == 6
	 ${word}=  Dancee
	   Log To Console  ${word}
	 END
	 IF 	${condion} == 7
	 ${word}=  Dancef
	   Log To Console  ${word}
	 END
	 IF 	${condion} == 8
	 ${word}=  Danceg
	   Log To Console  ${word}
	 END
	 IF 	${condion} == 9
	 ${word}=  Danceh
	   Log To Console  ${word}
	 END
	 IF 	${condion} == 10
   	${word}=  Song Ca
	   Log To Console  ${word}
	 END
	 IF 	${condion} == 11
	 ${word}=  Song Cb
	   Log To Console  ${word}
	 END
	 IF 	${condion} > 11
	 ${word}=  Song Ce
	   Log To Console  ${word}
	 END

When I ran this I got (condition 10):

==============================================================================
Anusha2                                                                       
==============================================================================
Test                                                                  ...brrrr
Test                                                                  | PASS |
------------------------------------------------------------------------------
Anusha2                                                               | PASS |
1 test, 1 passed, 0 failed
==============================================================================

Thanks for your response. I’ll try this solution.