Looping in Robot framework - robotframework

I would like to repeat the similar commands with replacing few variables in Robot framework. Could please suggest me how to do it?
Here is the sample code:
variable1 = ['abc']
varaible2 = ['123','456']
| | Run Keyword And Continue On Failure | testing | ${variable1} | ${variable2} | ${GetVal} | ${Check} |
variable3 = ['xyz']
varaible2 = ['678','789']
| | Run Keyword And Continue On Failure | testing | ${variable3} | ${variable4} | ${GetVal} | ${Check} |

Yes Robot framework supports for loops here is the example
:FOR ${animal} IN cat dog
\ Log ${animal}
\ Log 2nd keyword
Log Outside loop
For More Examples Please go through this link
http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#for-loops

Robot framework provides a "for" loop with the special keyword :FOR (see For Loops in the user guide)
| | :FOR | ${v2} | IN | #{variable2}
| | | Run keyword and continue on failure
| | | ... | testing | ${variable1} | ${v2} | ${GetVal} | ${Check}
Notice that the body of the loop has an extra level of indentation.
If you want to do nested loops you'll need to create a separate keyword for the nested loop. It very quickly becomes easier to write a single python keyword that does all of the looping and logic, as robot really isn't designed to be a general purpose programming language.

here is an example which loops for a given number
: FOR ${INDEX} IN RANGE 200
\ Log To Console ${INDEX}

The other answers are very good at explaining how to write a simple FOR loop in Robot Framework, so this is added clarity for your information.
First of all, the code to do as you're asking is as follows, assuming the various unknown variables are already defined elsewhere:
*** Test Cases ***
Do Your Test
:FOR ${INDEX} IN RANGE ${INCLUSIVE_STARTING_INDEX1} ${EXCLUSIVE_ENDING_INDEX1}
\ Run Keyword and Continue On Failure testing ${variable1} ${variable2} ${GetVal} ${Check}
:FOR ${INDEX} IN RANGE ${INCLUSIVE_STARTING_INDEX2} ${EXCLUSIVE_ENDING_INDEX2}
\ Run Keyword and Continue On Failure testing ${variable3} ${variable4} ${GetVal} ${Check}
Second, I need to clarify that FOR Loops in Robot Framework are NOT Keywords. They're distinctively separate entities at the most basic level in the language. I learned this by spending hours delving into the code, trying to figure out how it might be possible to code a nestable For loop. To save you the effort of trying, it isn't without coding your own customized keyword in Python.
Also, I should specify that I'm taking the liberty of assuming that you made a few typos in your question, and that your personalized keyword "testing" that you wrote somewhere else accepts a list object as its second input variable. If that is incorrect, let me know and I'll give you a more accurate answer.

If you want only one loop you can use
:FOR ${iTemp} IN #{listOfStudents}
\ Log ${iTemp}
\ Log GO_ON.
but you can't make loop inside loop
for that you should use keyword for that like below
First Loop
:FOR ${i} IN #{listOfStudents}
\ Log ${i}
\ Log OutSide Loop
Outside Loop
:FOR ${j} IN #{ListOfSubject}
\ Log ${j}
\ Log new Kewords.
Thats the way you can use loops in Robot Framework
Thasnks

For loop syntax was enhanced in Robot Framework 3.1. New syntax is as follows:
*** Test Cases ***
Example
FOR ${animal} IN cat dog
Log ${animal}
Log 2nd keyword
END
Log Outside loop
Second Example
FOR ${var} IN one two ${3} four ${five}
... kuusi 7 eight nine ${last}
Log ${var}
END

Related

Can you split keyword into multiple lines

I was trying to implement a keyword with arguments embedded in keyword, in a way that it is shown in Gherkin example. I have a keyword with multiple arguments. I was wondering if it is possible to split it to multiple lines? I wasn’t able to find this in the user guide. I tried to split as if it was a documentation, but with no luck.
*** Test Cases ***
test
When very long keyword ${argument_1}:${argument_2} with
... multiple arguments ${argument_4} is set to ${argument_5}
*** Test Cases ***
test
When very long keyword ${argument_1}:${argument_2} with \
... multiple arguments ${argument_4} is set to ${argument_5}
What is the standard solution here? Should I generally make shorter keywords?
Following your code to the letter, you basically have multiple errors of input separation.
Try something like this:
*** Test Cases ***
test 1
When very long keyword ${argument_1} ${argument_2}
... ${argument_4} ${argument_5}
test 2
When very long keyword ${argument_1} ${argument_2}
... ${argument_4} ${argument_5}
*** Keywords ***
When very long keyword
[Arguments] ${arg1} ${arg2} ${arg3}
... ${arg4} # You can also have new lines in arguments input!
Log My 4 arguments are: ${arg1}, ${arg2}, ${arg3}, ${arg4}
You can split long keywords with And like this:
*** Test Cases ***
Valid Login
Given login page is open
When valid username and password are inserted
And credentials are submitted
Then welcome page should be open
Cucumber has this option to split arguments but I never tried with RobotFramework.
Given the following people exist:
| name | email | phone |
| Aslak | aslak#email.com | 123 |
| Joe | joe#email.com | 234 |
| Bryan | bryan#email.org | 456 |

Log in console Gherkin steps with Robot Framework

I want to use Robot Framework to write and execute Test Cases in Gherkin format.
What I want is when I execute a Test Case, output in the console besides the name
of the Scenario, each step (When, Then...) and log as well if the step passes or not.
You could achieve such functionality with a listener that uses the listener interface of the framework.
The end_keyword listener method will be invoked during execution when a keyword is finished. It will get the keyword name and its attributes as a parameter, so you can log both the name and the status.
You have to filter it so only keywords starting with Given, When, Then will be logged on the console.
Example:
ROBOT_LISTENER_API_VERSION = 2
def start_test(name, attributes):
# Add an extra new line at the beginning of each test case to have everything aligned.
print(f'\n')
def end_keyword(name, attributes):
if name.startswith('Given') or name.startswith('When') or name.startswith('Then'):
print(f'{name} | {attributes["status"]} |')
Console output for the behavior-driven development example of the user guide.
robot --pythonpath . --listener listener.py test.robot
==============================================================================
Test
==============================================================================
Add two numbers
Given I have Calculator open | PASS |
.When I add 2 and 40 | PASS |
.Then result should be 42 | PASS |
Add two numbers | PASS |
------------------------------------------------------------------------------
Add negative numbers
Given I have Calculator open | PASS |
.When I add 1 and -2 | PASS |
.Then result should be -1 | PASS |
Add negative numbers | PASS |
------------------------------------------------------------------------------
Test | PASS |
2 critical tests, 2 passed, 0 failed
2 tests total, 2 passed, 0 failed
==============================================================================

Returning multiple PASS/FAIL

If I have a list of strings ['PASS', 'FAIL', 'PASS'], how can I return
multiple PASS or FAIL status, depending on the string? Right now I have something like:
test01
:FOR ${test} IN #{tests}
\ Log to Console ${test}
\ Should Match ${test} PASS
The robot framework will return:
test01
PASS
PASS
FAIL
test01 | FAIL |
'FAIL' does not match 'PASS'
Essentially I want one test to dynamically generate the TEST_STATUS for an arbitrary length list, and the results to look something like:
test01
PASS | PASS |
PASS | PASS |
FAIL
test01 | FAIL |
'FAIL' does not match 'PASS'
You have to create separate test cases, since a test case has exactly one status, PASS or FAIL.
However, there are ways to ensure that all values in the list are handled. The easiest, I think, is using a test case template, like this
Test Case
[Template] Should Be Equal
: FOR ${status} IN #{VALUES}
\ ${status} PASS
With template, all the steps are run in continue on failure mode, which means that a failure does not prevent the loop from finishing. Instead, they failure(s) are collected and used to create a final status.

Testcase level validations in Robot framework?

I would like to know is there any way to control the validations for testcase level. we have tags, which are testcase selection level. I have a testcase which covers addition and subtraction of two numbers.
Here my requirement, both actions are in the same testcase but, if I mention 'add' testcase will execute only addition part and similarly sub. if we didn't specify any specification then it has to run both the operations. IS there any way to control these kind of scenarios in Robot? kind of if/else scenario in testcase level. We will mention our input while running the script. Of course we can write it in different testcases like, one for Sub and another one for Add but, in my case i have total of 100+ testcases are with this kind of scenario.
Sample code:
| Setting | Value |
| * Test Cases * |
-----------------------------
| Testing1
| | [Tags] | PRIORITY:P0 | CATEGORY:NA | STC_DB_INDEX:NA
if {add}
| | Log | Addition of two numbers |
| | Run Keyword | addition | 20 | 25 |
if {sub}
| | Log | Subtraction of two numbers |
| | Run Keyword | sub | 10 | 5 |
The simplest solution is to split your test in two. Many QA experts think each test should test exactly one thing, and I've found that to be a successful strategy.
So, put your add validation in one test, your subtraction in another. Then when you specify the "add" tag, only the "add" tests will run.
Not sure if I understand what you need, but if you have a lot of repetition in your test you should consider a template approach like:
*** Test Cases ***
Add Variables Scenario [Template] Sum My Vars
${var1} ${var2} ${expectedResult1} # one line is one test
${var3} ${var4} ${expectedResult2}
Substract Variables Scenario [Template] Substract My Vars
${var1} ${var2} ${expectedResult1}
*** Keywords ***
Sum My Vars
[Arguments] ${value1} ${value2} ${result}
# do your validations ...
Substract My Vars
[Arguments] ${value1} ${value2} ${result}
# do other validations ...
Basically with this you can call one or other keyword and each sum / substraction will always generate a distinct test case without much code repetition.
If this is not what you are really looking for trying giving a bit more details and what you are really looking for

Looping through the content of a file in RobotFramework

How can I loop through the contents of a file within Robot Framework?
My file contents would be like this:
1001
1002
1003
1004
I want to read the contents one by one, assign it to a variable and then do some operations with it.
Robotframework has several built-in libraries that add a lot of functionality. Two that you can use for this task are the OperatingSystem library and the String library.
You can use the keyword Get File from the OperatingSystem library to read the file, and you can use the Split to Lines keyword from the String library to convert the file contents to a list of lines. Then it's just a matter of looping over the lines using a for loop.
For example:
*** Settings ***
| Library | OperatingSystem
| Library | String
*** Test Cases ***
| Example of looping over the lines in a file
| | ${contents}= | Get File | data.txt
| | #{lines}= | Split to lines | ${contents}
| | :FOR | ${line} | IN | #{lines}
| | | log | ${line} | WARN
This solve my issue same like yours !
${File}= Get File Path\\FileName.txt
#{list}= Split to lines ${File}
:FOR ${line} IN #{list}
\ Log ${line}
\ ${Value}= Get Variable Value ${line}
\ Log ${Value}
I am reading from 'text' file and 'Get Variable Value' is part of builtin library. Thanks!
Below is a list of different examples how to use FOR & While loops in your Robot Framework Test Cases.
http://robotframework.googlecode.com/svn/tags/robotframework-2.5.3/atest/testdata/running/for.txt
My strategy, that I've used successfully with .csv files, would be to create a Python-based keyword that will grab the nth item in a file. The way I did it involved importing the CSV Python library, so to give a more complete answer I'd have to know what file type you're trying to read from.

Resources