In my robot file for a specific test, I've defined the variable uarts_to_test to a list of numeric values under variables:
*** Variables ***
${uarts_to_test} ['0', '1', '2', '3']
Now I would like to loop though this list, and create the define -DTEST_UART# where # is the uart index, for every number listed in uarts_to_test. I would also like to add all of these defines to the variable ${make_options}. I've tried to create a simple routine under keywords:
*** Keywords ***
Determine which uarts to test
[Arguments] #{uarts_to_test}
:FOR ${item} IN #{uarts_to_test}
\ IF List Should Contain Value ${i}
\ ${make_options} = ${make_options} -DTEST_UART${i}
but I only get the error:
Variable '${make_options}' not found.
This is my solution. I return make options as a string and also as a list in case additional logic is needed with the items in the list.
*** Settings ***
Library Collections
*** Variables ***
${uarts_to_test} ['0', '1', '2', '3']
*** Test Cases ***
MakeOptionsTest
${make_options} ${make_optionsList} Determine which uarts to test ${uarts_to_test}
Log ${make_options}
Log List ${make_optionsList}
*** Keywords ***
Determine which uarts to test
[Arguments] ${uarts_to_test}
${make_optionsList} Create List
${uarts_to_test} Evaluate ${uarts_to_test}
:FOR ${item} IN #{uarts_to_test}
\ Append To List ${make_optionsList} -DTEST_UART${item}
${make_options} Evaluate " ".join(${make_optionsList})
[Return] ${make_options} ${make_optionsList}
This outputs in the console:
20210602 23:24:59.595 : INFO : -DTEST_UART0 -DTEST_UART1 -DTEST_UART2
-DTEST_UART3 20210602 23:24:59.596 : INFO : List length is 4 and it contains following items: 0: -DTEST_UART0 1: -DTEST_UART1 2:
-DTEST_UART2 3: -DTEST_UART3
I was not able to find ${i} in your code. There is also no declaration of ${make_options} that is probobaly why it is not found. You can use collection library, create list and append the items to it. like so
***Settings***
Library Collections
*** Variables ***
#{uarts_to_test} 0 1 2 3
***Test Cases***
test
#{make_options}= Create List
FOR ${uart} IN #{uarts_to_test}
Append To List ${make_options} -DTEST_UART${uart}
END
Log ${make_options}
this will be in the log of your ${make_options}:
['-DTEST_UART0', '-DTEST_UART1', '-DTEST_UART2', '-DTEST_UART3']
from the error Variable '${make_options}' not found. it says you are assigning variable ${make_options}, before defining its value.
if you take example of first iteration of loop, your variable ${make_options} is not defined before and you are assigning it to a variable.
you can simply define a variable ${mytext} and concatinate it in loop, like below:
*** Setting ***
Documentation test1
*** Variables ***
#{uarts_to_test} 0 1 2 3 4
${mytext} 'DTEST_UART'
*** Test Cases ***
demo testing
Determine which uarts to test #{uarts_to_test}
*** Keywords ***
Determine which uarts to test
[Arguments] #{uarts_to_test}
FOR ${item} IN #{uarts_to_test}
\ ${make_options}= Catenate ${mytext} ${item}
\ Log To Console ${make_options}
console output:
'DTEST_UART' 0
'DTEST_UART' 1
'DTEST_UART' 2
'DTEST_UART' 3
'DTEST_UART' 4
Related
I have assigned global variable as ${googlesite} = http://google.com and I want to use this variable in another robot file under variable section as
robot1.robot
${googlesite} = http://google.com
*** keywords ***
set suite variable ${googlesite}
robot2.robot
*** Variables ***
${googlelogin} = ${googlesite}/login.html
*** Keywords ***
log to console ${googlesite}-- Its printing as http://google.com
log to console ${googlelogin}-- printing only ./login.html
(not appending ${googlesite} from variables section)
You can do this by executing the variable assignment using a keyword.
So in robot1.robot, define a keyword to set this variable:
*** Keywords ***
Setup
Set Global Variable ${googlesite} http://google.com
Then import robot1.robot in robot2.robot as a resource and execute the Setup keyword anywhere before accessing the variable:
*** Settings ***
Resource robot1.robot
Suite Setup Setup
*** Test Cases ***
Test global variable
# The global variable is available in robot2.robot
log to console ${googlesite}
# Use it to form the new variable
${googlelogin} = Convert To String ${googlesite}/login.html
log to console ${googlelogin}
This will print:
Test global variable http://google.com
http://google.com/login.html
| PASS |
I can't see how the code you've provided is working at all given you're using log to consoles directly in keywords section and all the spacing is wrong.
You can import robot1.robot into robot2.robot and robot2.robot will have access without the need to set it as a suite variable.
robot1.robot:
*** Variables ***
${googlesite} http://google.com
robot2.robot:
*** Settings ***
Resource robot1.robot
*** Variables ***
${googlelogin} ${googlesite}/login.html
*** Test Cases ***
Check the Google variables are correct
log to console \nGoogle Site: ${googlesite}
log to console Google Login: ${googlelogin}
I wrote this simple minimal script to show how I suffer:
main.robot
Library Collections
Library BuiltIn
Library String
*** Variables ***
&{info} Create Dictionary
*** Test Cases ***
Case_00_Initialization
Log Hello 1 WARN
Set To Dictionary ${info} field1=A sample string
Log Hello 2 WARN
Running this code by
python -m robot -L TRACE --NoStatusRC main.robot
Gives me errors:
[ ERROR ] Error in file 'C:\test\main.robot' on line 7: Setting variable '&{info}' failed: Invalid dictionary variable item 'Create Dictionary'. Items must use 'name=value' syntax or be dictionary variables themselves.
==============================================================================
Main
==============================================================================
[ WARN ] Hello 1
Case_00_Initialization | FAIL |
No keyword with name 'Set To Dictionary' found.
------------------------------------------------------------------------------
Main | FAIL |
1 critical test, 0 passed, 1 failed
1 test total, 0 passed, 1 failed
==============================================================================
Output: C:\test\output.xml
Log: C:\test\log.html
Report: C:\test\report.html
The application is supposed to set a variable info in the initialization and it will be used in the next test cases. I do not want to use Set Global Variable however.
Please note that this is a minimal working example, do not suggest to set field1 at Variables section. It is not possible. Even that one will not solve the problem of No keyword with name 'Set To Dictionary' found.
In the Variables section you cannot use keywords - and this is exactly what you did with the Create Dictionary there.
You can add some key:values to it (like "field" , but you don't allow us that ;), or - you can initialize it to be an empty dictionary (e.g. like {} in python). The later is done by passing the special value &{Empty}:
*** Variables ***
&{info} &{Empty}
I eventually found what is wrong. I was missing the line for *** Settings *** I couldn't imagine that it does matter. Shame that RF does not have many full examples online.
This is the working code:
*** Settings ***
Library Collections
*** Variables ***
&{info}
*** Test Cases ***
Case_00_Initialization
Log Hello 1 WARN
Set To Dictionary ${info} field1=A sample string
Log Hello 2 WARN
I have trouble with assert keys in my code.
No keyword with name 'in {'name': '$.data[0].name'}' found.
my code is
*** Variables ***
&{name} name=$.data[0].name
*** Variables ***
Run keyword if 'name' in ${name} log name is in the log as expected
The way you've defined your test cases (assuming the second *** Variables *** is actually *** Test Cases ***), robot thinks Run keyword if is the name of a test case, and the first keyword is 'name' in ${name}
The solution is to give your test case a name.
There's also a problem that you have two spaces after 'name' which should give you a different error than what you're reporting. Also, the second table should be named *** Test Cases ***.
*** Test Cases ***
Example test case
Run keyword if 'name' in ${name} log name is in the log as expected
You should probably also use $name rather than ${name} so that robot injects the actual variable into the expression.
*** Test Cases ***
Example test case
Run keyword if 'name' in $name log name is in the log as expected
I'm playing around with command-line arguments and had something working both with / without giving a command-line argument, but suddenly it starts failing if I don't give a command-line argument.
On https://groups.google.com/g/robotframework-users/c/_5Usp-K4Dlw?pli=1 I read that adding a space before the variable and comparing it to a value like this '${ VAR}'==<value> should work to check if a variable is existing or not.
The code-snippet that was working before is:
*** Test Cases ***
My test
[Documentation] test to check if the SUT reacts as expected
${is_test}= Evaluate '${ VAR}'=='test'
Log To Console ${is_test}
Run Keyword If ${is_test} Log To Console VAR == test
After changing the code to (Removed '[Documentation]' since it was copied from another test):
*** Test Cases ***
My test
${is_test}= Evaluate '${ VAR}'=='test'
Log To Console ${is_test}
Run Keyword If ${is_test}
... Log To Console VAR == test
it suddenly started failing with: Variable '${ VAR}' not found. errors.
And after changing it back to the original it still fails.
I can't figure what I did wrong in the change.
Note: The company I'm working for uses RobotFramework version 3.0.4 (yes I know ancient)
Managed to solve it by adding ${VAR} with some default value to a *** Variables *** list. But still I don't understand why it was originally working without that list.
Here is how your test should look like if you want to check if variable is empty and do something based on that.
*** Variables ***
${VAR}= test
*** Test Cases ***
My test
Run Keyword If '${VAR}'=='${EMPTY}' Log To Console Variable is empty
... ELSE Log To Console Variable is not empty
If you want variable default value to be empty and execute some keyword only if it comes from command line set variable as empty, for example:
*** Variables ***
${VAR}= ${EMPTY}
*** Test Cases ***
My test
Run Keyword If '${VAR}'=='${EMPTY}' Log To Console Variable is not set
... ELSE Log To Console Variable is ${VAR}
Run your test from command-line without passing variable
$ robot sample.robot
==============================================================================
Sample
==============================================================================
My test Variable is not set
My test | PASS |
------------------------------------------------------------------------------
Sample | PASS |
1 test, 1 passed, 0 failed
==============================================================================
Now, run with passing variable
$ robot -v VAR:test sample.robot
==============================================================================
Sample
==============================================================================
My test Variable is test
My test | PASS |
------------------------------------------------------------------------------
Sample | PASS |
1 test, 1 passed, 0 failed
==============================================================================
P.S. About space inside variable, I think it's just typo in Google Groups. If it was working then variable might be globally accessible or defined somewhere else.
I want to use given library name as an argument in my keyword as in the following:
*** Settings ***
Library some_library WITH NAME some_lib_name
*** Keywords ***
FOO
[Arguments] ${some_lib_name} ${params}
${some_lib_name}.SEND param1
But the robot framework gives an error "No keyword with name '${some_lib_name}.SEND' found."
So is there a way to make it work?
You can use run keyword since it will evaluate variables before calling the keyword:
*** Keywords ***
FOO
[Arguments] ${some_lib_name} ${param1}
Run keyword ${some_lib_name}.SEND ${param1}