0
votes

I'm currently using Robot Framework to automate some tests.

Problem: I am trying to figure out a way to make variables imported from 'Import Variables' keyword globally available (--variablefile is not an option for me right now, sadly).

I already tried some workarounds, with no luck:

 1. Import Variables
 2. Get Variables available in current scope
 3. Loop through each variable and get its key and value
 4. Set each variable globally (using Set Global Variable)

The problem I faced in the above approach is that there are different types of data on my external file (scalar, lists, dicts), and therefore 'Set Global Variable' fails at some point when trying to set a dict. It complains about "Dictionary item 'no' does not contain '=' separator.".

I researched a bit and found that robot can't assign a dict type variable like this "Set Global Variable ${DICT_VAR} {"key1":"data1", "key2":"data2"}". Practical explanation can be found here robot-framework github tests.

Well, I'm thinking about building a small library to accomplish this and use it like: "Import Variables /path/to/variables.py scope=global", where the attribute scope could be one of the following: test, suite, global.

Well, that's my struggle, folks. Hopefully someone can help me with that. (:

EDIT: So, about not being able to use --variablefile option: Currently, I'm asking the user for some inputs at the beginning of test execution, and one of these inputs is a selection among existent external files. I know I could say to the user "Please provide --variablefile option with external file absolute path.", but I do not want that since it is less practical for the user.


[SOLVED] Conclusion: I realized that what I was trying to do was not meant to be done using robot. Robot is a tool to create and maintain tests, generate reports, etc. Managing many files with variables (and global variables) should be avoided in the .robot files. Then I came up with an external file (a python script) that just do all this dirty job of selecting files and setting global variables. At the end of this script I just call subprocess.run("robot", args) where args are all the parameters (-V, -v, -i, etc) that robot needs to begin the test execution. In the end I was able to actually use the --variablefile (-V) option in the external script.

1
Wouldn't from Variables import * work? - Sebastian Mendez
Can you elaborate on why the --variablefile is not an option? It seems that you're going down a path that requires some considerable effort and I've not yet heard a good justification for it. If you're concerned that a fixed file lacks the flexibility, I'd point you to the Robot Framework Variable Function or Class that allows for dynamic creation of variables. - A. Kootstra
@Sebastian, thanks for your input. I don't think I get your idea.. "from Variables" - Where is this module available? I see that there is one called robot.api.variables, but it might not be what you meant, I'm not sure. - Pedro Thaines
@A.Kootstra, thanks for your advice. I already read some of the "get_variables" documentation, it is almost what I would like to accomplish. So, about not being able to use --variablefile option: Currently, I'm asking the user for some inputs at the beginning of test execution, and one of these inputs is a selection among existent external files. I know I could say to the user "Please provide --variablefile option with external file absolute path.", but I do not want that since it is less practical for the user. I think you got the idea here now (: - Pedro Thaines
I'm presuming that with "user" you mean the Tester/QA person executing the test-run, as opposed to the test logging into a system with given credentials. - A. Kootstra

1 Answers

1
votes

Bear in mind that Global variables should be constant in nature. Event though it is possible to update Global variables from a keyword or Test Case, this should be an exceptional action. For regular updating of variables the Suite, Test Case and Keyword scopes should be used.

In the below example I use a YAML variable file that holds a nested set of values. YAML imports allows for the definition of Python Lists, Scalars and Dictionaries in a human readable format, which is what makes them so useful for these types of nested imports.

data.yaml

DATA:
  Set 1:
    Lisa:
      - list item 1
      - list item 2
    Dica:
      dict item 1: value 1
      dict item 2: value 2
    vara: variable value 1
  Set 2:
    Lisa:
      - list item 3
      - list item 4
    Dica:
      dict item 1: value 3
      dict item 2: value 4
    vara: variable value 2

The above script is loaded through Variables data.yaml statement below. The rest of the script then takes a specific sub-set of that structure and creates Global Variables from the items by looping through them.

create_globals.robot

*** Setting ***
Library    Collections    

Variables    data.yaml

*** Test Cases ***
Test Case
    Create Globals    Set 2
    No Operation


*** Keywords ***
Get Data Set
    [Arguments]    ${name}
    [Return]    ${DATA['${name}']}

Create Globals
    [Arguments]    ${name}
    ${dataset}    Get Data Set    ${name}
    @{global_var_names}    Get Dictionary Keys    ${dataset}
    :FOR    ${global_var_name}    IN    @{global_var_names}
    \    Set Global Variable    ${${global_var_name}}    ${dataset['${global_var_name}']}

Because fetching the data set itself is abstracted through a keyword, changing the source of the data to for example a command line import or even a database is relative small change.