I would like to ask for some help, trying to figure out how extracting values from dictionary works, when they are provided in different formats. I am using a dictionary as an embedded keyword argument. One of the keys is “meetings”, which would accept a single or multiple times, for example:
case: meetings = 13:00
case: meetings = 8:30 10:00 13:00
I am not really sure what is the implementation to handle such inputs. It seems that in first case, the code parses value as a string ( “13:00” ). And in second case, it creates a list of strings ( [“8:30” “10:00” “13:00”] ).
I need a list of values (times) and was not able to find a simple solution. Eventually I ended up counting colons to determine whether there is one or multiple times present in the value:
IF "${times}".count(":") == 1
@{times}= Evaluate ["${times}"]
END
It is a very crude solution and I hope there is a way to avoid it altogether.
Can someone please explain why I am getting different instance types for different inputs. And what would be the most elegant way to make it consistent?
I couldn’t find a keyword for getting a variable type, so came up with this which is might work for you:
${times}= Set Variable 13:00
TRY
# if var is string exception will thowen
Log ${{ type(${my_string}) }}
EXCEPT
@{times}= Create List ${times}
END
Log ${times} console=true
Calling the python type on 13:00 gives an exception and calls the Create List keyword, if ${times} is already a list the Log keyword doesn’t throw an exception and the EXCEPT block is skipped
I will keep the IF solution just for fewer lines of code, even though it looks clumsy. I will however borrow your syntax for creating list, which is indeed much more readable.
Do you perhaps know why such behaviour occurs in the first place, just for me to understand? I mean parsing dictionary values with 2 different types.
As Dave said it’s not clear how the variable/list is provided to your keyword.
But indeed if you require a dict as [Arguments] the unique value will work easily for extraction.
Here the value of key meetings is ‘13:00’ :
If its quaranteed that the input strings are always separated with single space and there’s no trailing/leading spaces, simple Split String is the easiest way imho.
Example;
*** Settings ***
Library String
*** Variables ***
${times_1} 13:00
${times_2} 8:30 10:00 13:00
*** Test Cases ***
Test Split
@{t1}= Split String ${times_1} ${SPACE}
@{t2}= Split String ${times_2} ${SPACE}
FOR ${time} IN @{t1}
Log t1:${time} console=${True}
END
FOR ${time} IN @{t2}
Log t2:${time} console=${True}
END
will print out:
Test Split ..t1:13:00
.t2:8:30
t2:10:00
t2:13:00
Test Split | PASS |
so t1 gets printed once as it should and t2 3 times, as it should, with correct times.
EDIT; Ah, @CharlieScene already said the same thing …
Hi, I will try to summarize my setting in a brief way:
I have a keyword that accepts a dictionary as an argument:
Select settings with provided values: [Arguments] &{properties}
Which is called like this in test case file:
Example with one time provided
Select settings with provided values:
... times=13:00
Example with multiple times provided
Select settings with provided values:
... times=8:30 10:00 13:00
That is how I got into situation, when in case of one provided time is parsed as a string. And multiple provided times are parsed as a list of strings (times). This is why simple solutions of converting to list, or splitting a string, did not work for me and got me lost. And still I didn’t figure out, why it behaves that way or whether I did something wrong with passing the values to keyword.
That said, thank you all for providing tips and solutions!