Looping in Robot Framework not incrementing/persisting a variable value - robotframework

I have the code below that doesn't seem to persist the value of a variable. I am trying to increment it per call however the increment is not persistent in the variable.
*** Settings ***
Library lib.py
*** Variables ***
${x} 0
${inc} 1
*** Keywords ***
My keyword
${x} = evaluate ${x}+${inc}
Log To Console ${x}
# [return] ${x}
*** Test Cases ***
Run endless loop
Run Endless Loop My keyword
=================================================================
lib.py
from robot.libraries.BuiltIn import BuiltIn
def call_keyword(keyword):
return BuiltIn().run_keyword(keyword)
def run_endless_loop(f):
while True:
call_keyword(f)
Am curious what's happening here...

Your keyword works fine, only you are incrementing a local variable.
So in every iteration x will be 0 and it will be incremented to 1.
You have to store the returned value on suite level using the Set Suite Variable keyword.
*** Variables ***
${x} 0
${inc} 1
*** Test Cases ***
Test
My keyword
My keyword
My keyword
*** Keywords ***
My keyword
${x} = evaluate ${x}+${inc}
Set Suite Variable ${x}
Log To Console ${x}

Related

Instantiate empty list in Robot Framework?

In the Robot Framework user guide, it states a variable value is a list or list-like, it is also possible to use it as a list variable like #{EXAMPLE} and There is also an empty list variable #{EMPTY} but I am not able to create an empty list. In the minimally reproducible example below, no matter how I set it up I get the error, TypeError: Expected argument 1 to be a list or list-like, got string instead in my test case. How can I create an empty list that doesn't re-assign itself to be a string?
*** Settings ***
Library Collections
Suite Setup Re-instantiate List
*** Variables ***
#{shouldBeList}= #{EMPTY}
*** Test Cases ***
Add something to the list
Collections.Append to list #{shouldBeList} Test
*** Keywords ***
Re-instantiate List
#{shouldBeList}= Create List ${EMPTY}
Set Suite Variable #{shouldBeList} #{shouldBeList}
# Results:
# Add something to the list | FAIL |
# TypeError: Expected argument 1 to be a list or list-like, got string instead.
I should have read the user guide more closely.
All variables should be assigned using the ${var} syntax, including lists and dicts. The #{var} and &{var} syntax should be used when you want to unpack the ${var}, using the # symbol if it's list-like and & if it's dict-like.
My above code works when written as:
*** Settings ***
Library Collections
Suite Setup Re-instantiate List
*** Variables ***
*** Test Cases ***
Add something to the list
Collections.Append to list ${shouldBeList} Test
*** Keywords ***
Re-instantiate List
${shouldBeList}= Create List
Set Suite Variable #{shouldBeList} #{shouldBeList}

In robot framework is there a method to print the variable value of the embedded argument in keyword rather than the variable name?

*** keywords ***
Do something on ${var1} and ${var2}
Log ${var1}
Log ${var2}
*** Test Cases ***
Testing
${id1} Set Variable variable1
${id2} Set Variable variable2
Do something on ${id1} and ${id2}
When we run the above robot testcase the logs display ${id1} and ${id2} as variables in the keyword.
KEYWORD ${id1} = BuiltIn . Set Variable variable1
KEYWORD ${id2} = BuiltIn . Set Variable variable2
KEYWORD Do something on ${id1} and ${id2}
Is it possible in robot to have the log print the value of the variable instead of the variable itself in such use case, where the embedded arguments are variables?
For example can we have log print
KEYWORD Do something on variable1 and variable2
Sometimes its worthy to read the official documentation.
Log To Console - https://robotframework.org/robotframework/latest/libraries/BuiltIn.html#Log%20To%20Console
Also, you have Log ${var1} and it should be Log ${var1} (more than one space acts as separator)

Test Template with Robot Framework cannot use variables

I have some problems using the robotframework template,how to get variables passed to the template?
Here is my code:
*** Keywords ***
re-random-value
${random int} = Evaluate random.randint(1, 5)
[Return] ${random-num}
*** Test Cases *** test1
[Template] test template
re-random-value # random-num is return value from keywords re-random-value
*** Keywords ***
test template
[Arguments] ${random-num}
log ${random-num}
when I run the test case test1, The result is re-random-value, not the number of values returned by the keyword re-random-value I expected
The documentation on Robot Framework Test Templates states the following:
... test cases with template contain only the arguments for the
template keyword.
Within the context of a test template an argument can never be a keyword, the approach in the example won't work as is.
Assuming for a moment that the keyword may change per line/test case an intermediate keyword can be constructed that takes the name of the keyword as an argument and executes it. In the below updated version of your example this is what is done. Using the FOR loop to generate multiple values.
*** Test Cases ***
test1
[Template] test template
FOR ${index} IN RANGE 1 5
re-random-value # random-num is return value from keywords re-random-value
END
*** Keywords ***
test template
[Arguments] ${keyword}
${value} Run Keyword ${keyword}
Log To Console ${value}
re-random-value
${random int} = Evaluate random.randint(1, 5) modules=random
[Return] ${random int}
Results in (bear in mind the randomness of the values):
==============================================================================
test1 1
3
2
3
| PASS |
------------------------------------------------------------------------------

Arguments in if statements are ignored 1/2 the time

*** variables ***
${x} 0
*** Test Cases ***
Test1
run keyword if ${x} == 1 run keywords
... print hi
... ELSE
... print hi
Test2
run keyword if ${x} == 0 run keywords
... print hi
... ELSE
... print hi
*** keywords ***
print
[arguments] ${x}
log to console ${x}
Output:
Test1 hi
Test1 | PASS |
------------------------------------------------------------------------------
Test2 | FAIL |
Keyword 'print' expected 1 argument, got 0.
------------------------------------------------------------------------------
What is going on here? Arguments at the second print work but are ignored at the first.
The difference is that in one case you're calling run keywords (with arguments) and in the other case you're running print (with arguments).
We can reformat your code to show how robot is looking at it:
run keyword if ${x} == 1
... run keywords print hi
... ELSE
... print hi
When the expression is false, you fall through and run print hi, and everything works.
When the case is true, robot runs run keywords print hi. run keywords treats each of its arguments as a separate keyword to run so it tries to run print, and then it tries to run hi. Since you aren't giving an argument to print, it throws the error.
The issue comes from you expecting the hi to be passed as an argument to print in the run keywords construct, but robot doesn't treat it that way, the hi is just another keyword to be ran.
In Run Keywords documentation there's a paragraph how to use keywords with arguments in it - you have to chain the keywords with an AND:
... keywords can also be run with arguments using upper case AND as a separator between keywords. The keywords are executed so that the first argument is the first keyword and proceeding arguments until the first AND are arguments to it. First argument after the first AND is the second keyword and proceeding arguments until the next AND are its arguments. And so on.
In your case:
run keyword if ${x} == 1 run keywords
... print hi AND No Operation
... ELSE
... print hi
, will now change the call to "run the keyword print with an argument 'hi', and then run the keyword No Operation" (which does literally nothing, comes in handy for situations like this).

Variable Declaration and Initialization in Robot Framework within a Test Cases block

I tried to Declare and Initialize a variable in Robot Framework using Selenium platform. But I'm getting an Error Keyword name cannot be empty.
I tried the following code
Integer:
*** Test Cases ***
Test Case 1
${item} ${0} # ${}
Boolean:
*** Test Cases ***
Test Case 2
${item} ${true} #${}
String:
*** Test Cases ***
Test Case 3
${item} Stackoverflow
Kindly assist me how to declare and initialize a variable within a Test Cases block in Robot Framework.
Reply for #Goralight
I'm getting an error
You need to use the Set Variable Keyword to assign values to Variables outside the Variable Header:
*** Test Cases ***
Test Case 1
${item} Set Variable ${0} #${}
${item} Set Variable ${true} #${}
${item} Set Variable Stackoverflow
The above assigns the variable you have given in your test cases to the correct value. (This will overwrite ${item} every time of course however) But this will assign the value, to the var ${item}.
Read the Docs about it here
Any questions please ask :)
In my opinion, the following is a more readable way to do it:
*** Test Cases ***
Test Case 1
${item} = Set Variable ${0} #${}
${item} = Set Variable ${true} #${}
${item} = Set Variable Stackoverflow
You will get an error if you do the following:
${item} = Stackoverflow
The reason is that this assignment is expecting a keyword Stackoverflow on right hand side.
Here is a working example of such assignment.
*** Test Cases ***
Test Case 1
${item} = Get My Value
Log ${item}
*** Keywords ***
Get My Value
${my text} = Set Variable Stackoverflow
[return] ${my text}

Resources