Zeinab Abbasimazar
Zeinab Abbasimazar

Reputation: 10479

How to pass arguments by reference to robot framework keywords?

I have a keyword in robot framework; it takes an argument, performs some process on it and returns it after all:

My Keyword Name
    [Arguments]    ${arg}
    # Some process on ${arg}
    [Return]       ${arg}

So it would be the usage:

${x} =    My Keyword Name    ${x}

Which implies that I gave the old value of ${x} to the keyword and it returned me the new value of it.

I want to make a call by reference on My Keyword Name, so I don't need to use an assignment for setting new value for ${x}. I have read the BuiltIn and UserGuide, but there was no line about this subject. Can anyone help me on this?

Upvotes: 2

Views: 22926

Answers (5)

Bryan Oakley
Bryan Oakley

Reputation: 386382

If ${x} is a mutable type such as a list or dictionary, you can pass the object itself. If it represents a scalar value such as a string or int, you can't do what you want. Your only choice is to return the new value and re-assign it to the original variable.

Upvotes: 3

Todor Minakov
Todor Minakov

Reputation: 20077

It actually comes down to mutable/immutable variables in python, and how they are passed to functions.

Details here in this answer, but in RF context it boils down to - you can change lists and dictionaries, and not strings and numbers (int, float). Example:

A testcase
    Log To Console      \n
    ${var}=     Create List   member1
    Log To Console      ${var}

    Mutate The List     ${var}
    Log To Console      ${var}

*** Keywords ***
Mutate The List
    [Arguments]     ${lst}
    Append To List      ${lst}    new one

The output when ran would be:

==============================================================================
A testcase                                                            

['member1']
['member1', 'new one']
| PASS |

, e.g. the variable defined in the case got changed by a keyword. The same can be done with dictionaries.

If you reassign the variable in the function though, it will not change; e.g. with a keyword like this:

Mutate The Dict
    [Arguments]     ${lst}
    ${lst}=     Create List    fsf
    Append To List      ${lst}    bogus

, the original variable ${var} will not be changed.
Why so? In short, in python variables are just identifiers ("names") to memory addresses; when you assign ${lst} to a new list, the variable now points to a new address in the memory, and further interactions don't change the original one.

Upvotes: 2

bp3
bp3

Reputation: 245

I'd spent some time before i got the solution!

* Variables
${someVar}    initial value

* Test Cases
[Check reference]
    Set this          \${someVar}    new value
    Should Be Equal    ${someVar}    new value

* Keywords
Set this
[Arguments]          ${varName}    ${value}
Set Test Variable    ${varName}    ${value}

The point is in the magic "\" char :)

Upvotes: 1

Orest
Orest

Reputation: 1

Welp I just ran into the same issue, as I was using a Run Keyword If statement in a For Loop. Knowing that if I used a keyword that returns a value, robot framework freaks out.

So I just thought of this as a potential solution. It'll use my example. It does have redundancy, but thats because you just have to in this case.

***Keywords***
| Increment | [Arguments] | ${var} |
| | ${var} | Evaluate | ${var} + 1 |
| | Set Test Variable | ${var} | ${var} |

Usage:

| Increment | ${idx} |
| Set Test Variable | ${idx} | ${var}

Now I'm not saying this is the best solution, but if you run into the scenario that you have to return a value to a variable with a keyword, and you're inside a "Run Keyword If", this should allow you to circumvent the issue. I don't really like it that much, but it gets the job done.

Upvotes: -1

Hemant Kulkarni
Hemant Kulkarni

Reputation: 193

It will work if you initialize the variable as

My Keyword Name
    [Arguments]    ${arg}
    ${arg} =    Set Variable    56
    [Return]       ${arg}

Test
    Log To Console  \n\nin Test
    ${x} =  Set Variable    0
    ${x} =    My Keyword Name    ${x}
    Log To Console  ${x}

Or

Can you explore whether you can make use of Set Global Variable or Set Test Variable?

Upvotes: 2

Related Questions