Get substring with Robot Framework - robotframework

I have a string "banana :is_good OR :bad and apple :is_sweet OR :bitter and..."
I want to get all the characters between ":" characters.
(so in upper case I would get "is_good OR " and "is_sweet OR ")
What is the simplest way to do it with Robot Framework? Substring/Get Regexp Matches/?
Or if it is better to do with Python, how to do it?

As you described in your question there are a lot of possibilities. For example you can use Evaluate keyword and treat it as python problem. Below code should work:
***Variables***
${text} banana :is_good OR :bad and apple :is_sweet OR :bitter and...
*** Test Cases ***
Test
${searched_text}= Evaluate [x for i,x in enumerate("""${text}""".split(":")) if i%2 !=0 ]
Log ${searched_text}

You can use python's re module and the evaluate keyword:
*** Variables ***
${string} banana :is_good OR :bad and apple :is_sweet OR :bitter and...
#{expected} is_good OR${SPACE} bad and apple${SPACE} is_sweet OR${SPACE}
*** Test Cases ***
Example
#{substrings}= evaluate re.findall(r'(?<=:)[^:]+(?=:)', $string)
Should be equal ${substrings} ${expected}

Related

Template keywords can't handle line break in RF 3.2.1

This test case if working fine in Robot Framework 3.1.2 but in 3.2.1 I'm getting error message:
Setting 'Template' accepts only one value, got 2.
I can't see that there is any updates to the documentation that explains this. Any ideas?
*** Test Cases ***
Test Case
[Template] The result of ${calculation}
... should be ${expected}
1 + 1 2
2 + 2 4
*** Keywords ***
The result of ${calculation} should be ${expected}
${result} = Evaluate ${calculation}
Should Be Equal As Integers ${result} ${expected}
The ... marks an argument boundary. What you did is exactly the same as this:
[Template] The result of ${calculation} should be ${expected}
Like the error says, the [Template] setting only accepts a single argument but you're passing two. You cannot define the keyword on multiple lines.
It appears that the old (pre 3.2) parser may have been a bit lax and allowed you to split the template keyword on multiple lines. The new parser doesn't allow that.

Robotframework Change testcase name with variable

Is there any possible to change testcase name with variable like below?
(I don't want to change name from python side)
*** Variables ***
${country} US
*** Test Cases ***
test_${country}
As far as I know, it isn't possible to use a variable inside a test case name. It follows the same logic as normal Python functions, so normally, it isn't possible.
Instead, you can use the variable in the setup or in the test case directly to modify it's behaviour.
If you want to generate test cases based on a variable, you can write a (python) script that can generate the needed file/test cases with the corresponding values. Or, even better, use an Model-Based Testing tool to produce them.
Yes, you can. The way you have shown it should work. Are you facing any issue with that? If yes, pls provide the detailed error.
Yes this is supported.
example:-
*** Test Cases ***
Test title ${name}
[Tags] DEBUG
Log Welcome ${name}
output:-
robot --variable name:sample eg.robot

Use "run keyword if" to call a function with a string argument, but without altering the string

I ran into an odd issue so I wrote this example where I call "print ${dir}" twice:
*** Variables ***
${dir} = "c:\\temp"
*** Test Cases ***
Test
print ${dir}
run keyword if 1 == 1 print ${dir}
*** Keywords ***
print ${input1}
log to console \r${input1}
Output:
"c:\temp"
"c: emp"
What do I need to do to make "print ${dir}" print the same thing each time?
The problem stems from the fact you're using the embedded argument syntax. In order for robot to know what keyword to call, it must first do expansion of the variable before calling the keyword. That removes one layer of backslashes. Then, when your keyword passes what's left to the log to console keyword it sees \t as a tab character, which is why you see a tab character rather than the backslash and the letter "t".
One solution is to use traditional arguments rather than embedded arguments. The following example gives the same output for both times the keyword is called:
*** Variables ***
${dir} = "c:\\temp"
*** Test Cases ***
Test
print ${dir}
run keyword if 1 == 1 print ${dir}
*** Keywords ***
print
[Arguments] ${input1}
log to console \r${input1}
It seems to me that the Run Keyword If keyword does some additional escaping of the backslashes. By adding 1 more backslash you'll see it happen in the first example as well.
To overcome this issue is to switch from backslashes () to forward slashes (/). This works on both *nix and Windows based systems.
*** Variables ***
${dir} = "c:\\temp"
to
*** Variables ***
${dir} = "c:/temp"
This still makes a valid path on Windows. So functionally the path reference will work as well.

Robot Framework Set test documentation multiline

I would like use KW "Set test documentation" with multiline with RobotFW
The return to the line (\n) does not work with this KW
Someone have solution?
Setting multiline documentation is tricky because robot has some odd rules about its documentation. From the user guide section titled Documentation Formatting:
Starting from Robot Framework 2.7.2, all regular text in the formatted HTML documentation is represented as paragraphs. In practice, lines separated by a single newline will be combined in a paragraph regardless whether the newline is added manually or automatically. Multiple paragraphs can be separated with an empty line (i.e. two newlines) and also tables, lists, and other specially formatted blocks discussed in subsequent sections end a paragraph.
In a nutshell, that means that each line needs to end with two newlines.
Example:
*** Variables ***
${var1} this is var1
${var2} this is var2
*** Test Cases ***
Example of setting multiline test documentation
set test documentation
... var1: ${var1}\n\nvar2: ${var2}
The above will appear in log.html like this:
If your goal is to document the values of variables, robot also supports a simple markup for creating tables. The following example shows how to create a table. In this example I use the ability to append to the documentation rather than replace it:
*** Variables ***
${var1} this is var1
${var2} this is var2
*** Test Cases ***
Example 2: documentation with embedded table
set test documentation
... | var1 | ${var1} | \n
set test documentation
... | var2 | ${var2} | \n append=True
The above will appear in log.html like this:
I am not sure if we can do that directly, i found a workaround after taking reference from Bryan's reply on this thread.
Testcase level variables in [Documentation] for robot framework
Here multi lines are first mentioned in [Documentation] section and then this section can be used by Set test documentation kw.
*** Variables***
${SystemUnderTest} Staging
*** Test cases***
Device Test
Set Test Variable ${device} iPhone
[Documentation] Device is:
... System is: ${SystemUnderTest}
Substitute vars in documentation
*** Keywords ***
Substitute vars in documentation
${doc}= replace variables ${test documentation} # This will substitute the variables in documentation with their values , ${test documentation} is an inbuilt keyword which actually parse the content of [Documentation]
set test documentation ${doc} append=True #now the set test docuemntation will take the multi line input from documentation section
refer below link for further details http://robotframework.org/robotframework/latest/libraries/BuiltIn.html#Set%20Test%20Documentation

Dictionary as variable in Robot Framework: code runs ok but the IDE yields error

I'm trying to set up a dictionary as a variable (so I can use it as a Resource and access its values from another file) and there is something that is driving me crazy.
Here is the code I have (just for testing purposes):
*** Settings ***
Documentation Suite description
Library Collections
*** Variables ***
&{SOME DICT} key1=value1 key2=value2
*** Test Cases ***
Dict Test # why $ instead of &?
${RANDOM VAR}= Get From Dictionary ${SOME DICT} key1
Log ${RANDOM VAR} WARN
If I run that, I got the expected result ([ WARN ] value1) BUT the IDE (PyCharm) is complaining about that ${SOME DICT} variable is not defined, and the dictionary declaration is not highlighted the same as variable or a list.
If I change that to &{SOME DICT} the IDE won't complain anymore, but the test fails with the following output:
Dict Test | FAIL |
Keyword 'Collections.Get From Dictionary' got positional argument after named arguments.
That is puzzling me to no end: why I have to use a $ instead of a & if it's a dictionary to make it work? Is there something I am doing wrong and it is just running by luck?
Thanks for any advice or guidance you may have!
Have a look into "Get from Dictionary" libdoc,looks like example is showing the same as your working snippet:
Name: Get From Dictionary
Source: Library (Collections)
Arguments: [dictionary, key]
Returns a value from the given ``dictionary`` based on the given ``key``.
If the given ``key`` cannot be found from the ``dictionary``, this
keyword fails.
The given dictionary is never altered by this keyword.
Example:
| ${value} = | Get From Dictionary | ${D3} | b |
=>
| ${value} = 2
Keyword implementation details are as follows:
try:
return dictionary[key]
except KeyError:
raise RuntimeError("Dictionary does not contain key '%s'." % key)
So indeed, Robot sends representation of dict content and not dict name thus value for key can be returned.
This is the same as direct call in python:
a = {u'key1': u'value1', u'key2': u'value2'}
print(a['key1'])
In the end, libdoc for that KW is not straightforward but your PyCharm plugin for Robot does not work properly in this case.
In RED Robot Editor (Eclipse based), proper case does not rise any warnings in editor, wrong-case provides error marker about arguments (better but still not clear what is exactly wrong. Blame minimalistic libdoc info).
ps. I am lead of RED project to be clear.
Simple Example to Use Key Value Variable in robot framework
Set value to dictionary
Get value from dictionary
&{initValues} Create Dictionary key1=value1 key2=value2
Set To Dictionary ${initValues} key1=newvalue1
Set To Dictionary ${initValues} key2=newvalue2
Set To Dictionary ${initValues} key3=newvalue3
${value} Get From Dictionary ${intialValues} key1

Resources