{"id":15018736,"url":"https://github.com/snooz82/robotframework-datadriver","last_synced_at":"2025-04-04T10:06:12.586Z","repository":{"id":42163883,"uuid":"166381769","full_name":"Snooz82/robotframework-datadriver","owner":"Snooz82","description":"Library to provide Data-Driven testing with CSV tables to Robot Framework","archived":false,"fork":false,"pushed_at":"2024-06-08T14:37:58.000Z","size":837,"stargazers_count":141,"open_issues_count":17,"forks_count":39,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-04-04T09:44:52.521Z","etag":null,"topics":["datadriven","datadriventesting","python3","robotframework"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Snooz82.png","metadata":{"files":{"readme":"Readme.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-01-18T09:43:31.000Z","updated_at":"2025-03-09T12:00:28.000Z","dependencies_parsed_at":"2024-06-08T15:47:00.011Z","dependency_job_id":"a57ae133-c36c-401f-a4ba-0546a23c730d","html_url":"https://github.com/Snooz82/robotframework-datadriver","commit_stats":{"total_commits":134,"total_committers":12,"mean_commits":"11.166666666666666","dds":"0.16417910447761197","last_synced_commit":"e6eeb75be7b1aad188ae9c0ce4559e5a97b857d5"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snooz82%2Frobotframework-datadriver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snooz82%2Frobotframework-datadriver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snooz82%2Frobotframework-datadriver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snooz82%2Frobotframework-datadriver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Snooz82","download_url":"https://codeload.github.com/Snooz82/robotframework-datadriver/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247157281,"owners_count":20893220,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["datadriven","datadriventesting","python3","robotframework"],"created_at":"2024-09-24T19:52:23.259Z","updated_at":"2025-04-04T10:06:12.559Z","avatar_url":"https://github.com/Snooz82.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"===================================================\nDataDriver for Robot Framework®\n===================================================\n\nDataDriver is a Data-Driven extension for Robot Framework®.\nThis document explains how to use the DataDriver library listener. For\ninformation about installation, support, and more, please visit the\n`project page \u003chttps://github.com/Snooz82/robotframework-datadriver\u003e`_\n\nFor more information about Robot Framework®, see https://robotframework.org.\n\nDataDriver is used/imported as Library but does not provide keywords\nwhich can be used in a test. DataDriver uses the Listener Interface\nVersion 3 to manipulate the test cases and creates new test cases based\non a Data-File that contains the data for Data-Driven Testing. These\ndata file may be .csv , .xls or .xlsx files.\n\nData Driver is also able to cooperate with Microsoft PICT. An Open\nSource Windows tool for data combination testing. Pict is able to\ngenerate data combinations based on textual model definitions.\nhttps://github.com/Microsoft/pict\n\nIt is also possible to implement own DataReaders in Python to read\nyour test data from some other sources, like databases or json files.\n\n\nInstallation\n------------\n\nIf you already have Python \u003e= 3.6 with pip installed, you can simply\nrun:\n\n``pip install --upgrade robotframework-datadriver``\n\n\nExcel Support\n~~~~~~~~~~~~~\n\nFor file support of ``xls`` or ``xlsx`` file you need to install the extra XLS or the dependencies.\nIt contains the dependencies of pandas, numpy and xlrd. Just add [XLS] to your installation.\nNew since version 3.6.\n\n``pip install --upgrade robotframework-datadriver[XLS]``\n\n\nPython 2\n~~~~~~~~\n\nor if you have Python 2 and 3 installed in parallel you may use\n\n``pip3 install --upgrade robotframework-datadriver``\n\nDataDriver is compatible with Python 2.7 only in Version 0.2.7.\n\n``pip install --upgrade robotframework-datadriver==0.2.7``\n\nBecause Python 2.7 is deprecated, there are no new feature to python 2.7 compatible version.\n\n\nTable of contents\n-----------------\n\n-  `What DataDriver Does`_\n-  `How DataDriver Works`_\n-  `Usage`_\n-  `Structure of Test Suite`_\n-  `Structure of data file`_\n-  `Accessing Test Data From Robot Variables`_\n-  `Data Sources`_\n-  `File Encoding and CSV Dialect`_\n-  `Custom DataReader Classes`_\n-  `Selection of Test Cases to Execute`_\n-  `Configure DataDriver by Pre-Run Keyword`_\n-  `Pabot and DataDriver`_\n\n\nWhat DataDriver Does\n--------------------\n\nDataDriver is an alternative approach to create Data-Driven Tests with\nRobot Framework®. DataDriver creates multiple test cases based on a test\ntemplate and data content of a csv or Excel file. All created tests\nshare the same test sequence (keywords) and differ in the test data.\nBecause these tests are created on runtime only the template has to be\nspecified within the robot test specification and the used data are\nspecified in an external data file.\n\n\nRoboCon 2020 Talk\n~~~~~~~~~~~~~~~~~\n\n.. image:: https://img.youtube.com/vi/RtEUr1i4x3s/0.jpg\n   :target: https://www.youtube.com/watch?v=RtEUr1i4x3s\n\nBrief overview what DataDriver is and how it works at the RoboCon 2020 in Helsiki.\n\n\nAlternative approach\n~~~~~~~~~~~~~~~~~~~~\n\nDataDriver gives an alternative to the build in data driven approach\nlike:\n\n.. code :: robotframework\n\n    *** Settings ***\n    Resource    login_resources.robot\n\n    Suite Setup    Open my Browser\n    Suite Teardown    Close Browsers\n    Test Setup      Open Login Page\n    Test Template    Invalid login\n\n\n    *** Test Cases ***       User        Passwort\n    Right user empty pass    demo        ${EMPTY}\n    Right user wrong pass    demo        FooBar\n\n    Empty user right pass    ${EMPTY}    mode\n    Empty user empty pass    ${EMPTY}    ${EMPTY}\n    Empty user wrong pass    ${EMPTY}    FooBar\n\n    Wrong user right pass    FooBar      mode\n    Wrong user empty pass    FooBar      ${EMPTY}\n    Wrong user wrong pass    FooBar      FooBar\n\n    *** Keywords ***\n    Invalid login\n        [Arguments]    ${username}    ${password}\n        Input username    ${username}\n        Input pwd    ${password}\n        click login button\n        Error page should be visible\n\nThis inbuilt approach is fine for a hand full of data and a hand full of\ntest cases. If you have generated or calculated data and specially if\nyou have a variable amount of test case / combinations these robot files\nbecome quite a pain. With DataDriver you may write the same test case\nsyntax but only once and deliver the data from en external data file.\n\nOne of the rare reasons when Microsoft® Excel or LibreOffice Calc may be\nused in testing… ;-)\n\n`See example test suite \u003c#example-suite\u003e`__\n\n`See example csv table \u003c#example-csv\u003e`__\n\n\nHow DataDriver Works\n--------------------\n\nWhen the DataDriver is used in a test suite it will be activated before\nthe test suite starts. It uses the Listener Interface Version 3 of Robot\nFramework® to read and modify the test specification objects. After\nactivation it searches for the ``Test Template`` -Keyword to analyze the\n``[Arguments]`` it has. As a second step, it loads the data from the\nspecified data source. Based on the ``Test Template`` -Keyword, DataDriver\ncreates as much test cases as data sets are in the data source.\n\nIn the case that data source is csv (Default)\nAs values for the arguments of the ``Test Template`` -Keyword, DataDriver\nreads values from the column of the CSV file with the matching name of the\n``[Arguments]``.\nFor each line of the CSV data table, one test case will be created. It\nis also possible to specify test case names, tags and documentation for\neach test case in the specific test suite related CSV file.\n\n\nUsage\n-----\n\nData Driver is a \"Library Listener\" but does not provide keywords.\nBecause Data Driver is a listener and a library at the same time it\nsets itself as a listener when this library is imported into a test suite.\n\nTo use it, just use it as Library in your suite. You may use the first\nargument (option) which may set the file name or path to the data file.\n\nWithout any options set, it loads a .csv file which has the same name\nand path like the test suite .robot .\n\n\n\n**Example:**\n\n.. code :: robotframework\n\n    *** Settings ***\n    Library    DataDriver\n    Test Template    Invalid Logins\n\n    *** Keywords ***\n    Invalid Logins\n        ...\n\n\nStructure of Test Suite\n-----------------------\n\n\nRequirements\n~~~~~~~~~~~~\n\nIn the Moment there are some requirements how a test\nsuite must be structured so that the DataDriver can get all the\ninformation it needs.\n\n - only the first test case will be used as a template. All other test\n   cases will be deleted.\n - Test cases have to be defined with a\n   ``Test Template`` in Settings secion. Reason for this is,\n   that the DataDriver needs to know the names of the test case arguments.\n   Test cases do not have named arguments. Keywords do.\n - The keyword which is used as\n   ``Test Template`` must be defined within the test suite (in the same\n   \\*.robot file). If the keyword which is used as ``Test Template`` is\n   defined in a ``Resource`` the DataDriver has no access to its\n   arguments names.\n\n\nExample Test Suite\n~~~~~~~~~~~~~~~~~~\n\n.. code :: robotframework\n\n    ***Settings***\n    Library           DataDriver\n    Resource          login_resources.robot\n    Suite Setup       Open my Browser\n    Suite Teardown    Close Browsers\n    Test Setup        Open Login Page\n    Test Template     Invalid Login\n\n    *** Test Case ***\n    Login with user ${username} and password ${password}    Default    UserData\n\n    ***** *Keywords* *****\n    Invalid login\n        [Arguments]    ${username}    ${password}\n        Input username    ${username}\n        Input pwd    ${password}\n        click login button\n        Error page should be visible\n\nIn this example, the DataDriver is activated by using it as a Library.\nIt is used with default settings.\nAs ``Test Template`` the keyword ``Invalid Login`` is used. This\nkeyword has two arguments. Argument names are ``${username}`` and\n``${password}``. These names have to be in the CSV file as column\nheader. The test case has two variable names included in its name,\nwhich does not have any functionality in Robot Framework®. However, the\nData Driver will use the test case name as a template name and\nreplaces the variables with the specific value of the single generated\ntest case.\nThis template test will only be used as a template. The specified data\n``Default`` and ``UserData`` would only be used if no CSV file has\nbeen found.\n\n\nStructure of data file\n----------------------\n\n\nmin. required columns\n~~~~~~~~~~~~~~~~~~~~~\n\n-  ``*** Test Cases ***`` column has to be the first one.\n-  *Argument columns:* For each argument of the ``Test Template``\n   keyword one column must be existing in the data file as data source.\n   The name of this column must match the variable name and syntax.\n\n\noptional columns\n~~~~~~~~~~~~~~~~\n\n-  *[Tags]* column may be used to add specific tags to a test case. Tags\n   may be comma separated.\n-  *[Documentation]* column may be used to add specific test case\n   documentation.\n\n\nExample Data file\n~~~~~~~~~~~~~~~~~\n\n+-------------+-------------+-------------+-------------+------------------+\n| \\**\\* Test  | ${username} | ${password} | [Tags]      | [Documentation]  |\n| Cases \\**\\* |             |             |             |                  |\n|             |             |             |             |                  |\n+=============+=============+=============+=============+==================+\n| Right user  | demo        | ${EMPTY}    | 1           | This is a test   |\n| empty pass  |             |             |             | case             |\n|             |             |             |             | documentation of |\n|             |             |             |             | the first one.   |\n+-------------+-------------+-------------+-------------+------------------+\n| Right user  | demo        | FooBar      | 2,3,foo     | This test        |\n| wrong pass  |             |             |             | case has         |\n|             |             |             |             | the Tags         |\n|             |             |             |             | 2,3 and foo      |\n|             |             |             |             | assigned.        |\n+-------------+-------------+-------------+-------------+------------------+\n|             | ${EMPTY}    | mode        | 1,2,3,4     | This test        |\n|             |             |             |             | case has a       |\n|             |             |             |             | generated        |\n|             |             |             |             | name based       |\n|             |             |             |             | on template      |\n|             |             |             |             | name.            |\n+-------------+-------------+-------------+-------------+------------------+\n|             | ${EMPTY}    | ${EMPTY}    |             |                  |\n+-------------+-------------+-------------+-------------+------------------+\n|             | ${EMPTY}    | FooBar      |             |                  |\n+-------------+-------------+-------------+-------------+------------------+\n|             | FooBar      | mode        |             |                  |\n+-------------+-------------+-------------+-------------+------------------+\n|             | FooBar      | ${EMPTY}    |             |                  |\n+-------------+-------------+-------------+-------------+------------------+\n|             | FooBar      | FooBar      |             |                  |\n+-------------+-------------+-------------+-------------+------------------+\n\nIn this data file, eight test cases are defined. Each line specifies one\ntest case. The first two test cases have specific names. The other six\ntest cases will generate names based on template test cases name with\nthe replacement of variables in this name. The order of columns is\nirrelevant except the first column, ``*** Test Cases ***``\n\nSupported Data Types\n~~~~~~~~~~~~~~~~~~~~\n\nIn general DataDriver supports any Object that is handed over from the DataReader.\nHowever the text based readers for csv, excel and so do support different types as well.\nDataDriver supports Robot Framework® Scalar variables as well as Dictionaries and Lists.\nIt also support python literal evaluations.\n\nScalar Variables\n^^^^^^^^^^^^^^^^\n\nThe Prefix ``$`` defines that the value in the cell is taken as in Robot Framework® Syntax.\n``String`` is ``str``, ``${1}`` is ``int`` and ``${None}`` is NoneType.\nThe Prefix only defines the value typ. It can also be used to assign a scalar to a dictionary key.\nSee example table: ``${user}[id]``\n\n\nDictionary Variables\n^^^^^^^^^^^^^^^^^^^^\n\nDictionaries can be created in different ways.\n\nOne option is, to use the prefix ``\u0026``.\nIf a variable is defined that was (i.e. ``\u0026{dict}``) the cell value is interpreted the same way,\nthe BuiltIn keyword `Create Dictionary \u003chttps://robotframework.org/robotframework/latest/libraries/BuiltIn.html#Create%20Dictionary\u003e`_ would do.\nThe arguments here are comma (``,``) separated.\nSee example table: ``\u0026{dict}``\n\nThe other option is to define scalar variables in dictionary syntax like ``${user}[name]`` or ``${user.name}``\nThat can be also nested dictionaries. DataDriver will create Robot Framework® (DotDict) Dictionaries, that can be accessed with ``${user.name.first}``\nSee example table: ``${user}[name][first]``\n\n\nList Variables\n^^^^^^^^^^^^^^\n\nLists can be created with the prefix ``@`` as comma (``,``) separated list.\nSee example table: ``@{list}``\n\nBe aware that a list with an empty string has to be the cell content `${Empty}`.\n\nPython Literals\n^^^^^^^^^^^^^^^\n\nDataDriver can evaluate Literals.\nIt uses the prefix ``e`` for that. (i.e. ``e{list_eval}``)\nFor that it uses `BuiltIn Evaluate \u003chttps://robotframework.org/robotframework/latest/libraries/BuiltIn.html#Evaluate\u003e`_\n\nSee example table: ``e{user.chk}``\n\n\n+--------------------------+-----------------------+---------------+-------------------------+-----------------------------+------------------------------------------+--------------------------+-------------------+-------------------+----------------------------+-------------------------+------------------------------------------------------------------+\n|  ``*** Test Cases ***``  |  ``${scalar}``        |  ``@{list}``  |  ``e{list_eval}``       |  ``\u0026{dict}``                |  ``e{dict_eval}``                        |  ``e{eval}``             |  ``${exp_eval}``  |  ``${user}[id]``  |  ``${user}[name][first]``  |  ``${user.name.last}``  |  ``e{user.chk}``                                                 |\n+--------------------------+-----------------------+---------------+-------------------------+-----------------------------+------------------------------------------+--------------------------+-------------------+-------------------+----------------------------+-------------------------+------------------------------------------------------------------+\n|  ``One``                 |  ``Sum List``         |  ``1,2,3,4``  |  ``[\"1\",\"2\",\"3\",\"4\"]``  |  ``key=value``              |  ``{'key': 'value'}``                    |  ``[1,2,3,4]``           |  ``10``           |  ``1``            |  ``Pekka``                 |  ``Klärck``             |  ``{'id': '1', 'name': {'first': 'Pekka', 'last': 'Klärck'}}``   |\n+--------------------------+-----------------------+---------------+-------------------------+-----------------------------+------------------------------------------+--------------------------+-------------------+-------------------+----------------------------+-------------------------+------------------------------------------------------------------+\n|  ``Two``                 |  ``Should be Equal``  |  ``a,b,c,d``  |  ``[\"a\",\"b\",\"c\",\"d\"]``  |  ``key,value``              |  ``{'key': 'value'}``                    |  ``True``                |  ``${true}``      |  ``2``            |  ``Ed``                    |  ``Manlove``            |  ``{'id': '2', 'name': {'first': 'Ed', 'last': 'Manlove'}}``     |\n+--------------------------+-----------------------+---------------+-------------------------+-----------------------------+------------------------------------------+--------------------------+-------------------+-------------------+----------------------------+-------------------------+------------------------------------------------------------------+\n|  ``Three``               |  ``Whos your Daddy``  |  ``!,\",',$``  |  ``[\"!\",'\"',\"'\",\"$\"]``  |  ``z,value,a,value2``       |  ``{'a': 'value2', 'z': 'value'}``       |  ``{'Daddy' : 'René'}``  |  ``René``         |  ``3``            |  ``Tatu``                  |  ``Aalto``              |  ``{'id': '3', 'name': {'first': 'Tatu', 'last': 'Aalto'}}``     |\n+--------------------------+-----------------------+---------------+-------------------------+-----------------------------+------------------------------------------+--------------------------+-------------------+-------------------+----------------------------+-------------------------+------------------------------------------------------------------+\n|  ``4``                   |  ``Should be Equal``  |  ``1``        |  ``[\"1\"]``              |  ``key=value``              |  ``{'key': 'value'}``                    |  ``1``                   |  ``${1}``         |  ``4``            |  ``Jani``                  |  ``Mikkonen``           |  ``{'id': '4', 'name': {'first': 'Jani', 'last': 'Mikkonen'}}``  |\n+--------------------------+-----------------------+---------------+-------------------------+-----------------------------+------------------------------------------+--------------------------+-------------------+-------------------+----------------------------+-------------------------+------------------------------------------------------------------+\n|  ``5``                   |  ``Should be Equal``  |               |  ``[]``                 |  ``a=${2}``                 |  ``{'a':2}``                             |  ``\"string\"``            |  ``string``       |  ``5``            |  ``Mikko``                 |  ``Korpela``            |  ``{'id': '5', 'name': {'first': 'Mikko', 'last': 'Korpela'}}``  |\n+--------------------------+-----------------------+---------------+-------------------------+-----------------------------+------------------------------------------+--------------------------+-------------------+-------------------+----------------------------+-------------------------+------------------------------------------------------------------+\n|  ``6``                   |  ``Should be Equal``  |  ``[1,2]``    |  ``[\"[1\",\"2]\"]``        |  ``key=value,key2=value2``  |  ``{'key': 'value', 'key2': 'value2'}``  |  ``None``                |  ``${none}``      |  ``6``            |  ``Ismo``                  |  ``Aro``                | ``{'id': '6', 'name': {'first': 'Ismo', 'last': 'Aro'}}``        |\n+--------------------------+-----------------------+---------------+-------------------------+-----------------------------+------------------------------------------+--------------------------+-------------------+-------------------+----------------------------+-------------------------+------------------------------------------------------------------+\n\n\nAccessing Test Data From Robot Variables\n----------------------------------------\n\nIf neccesary it is possible to access the fetched data tables directly from a Robot Framework® variable.\nThis could be helpfull in Test Setup or in Suite Setup.\n\nThere are three variables available within the Data-Driven Suite:\n\n@{DataDriver_DATA_LIST}\n~~~~~~~~~~~~~~~~~~~~~~~\n\nA list as suite variable containing a robot dictionary for each test case that is selected for execution.\n\n.. code :: json\n\n    [\n      {\n        \"test_case_name\": \"Right user empty pass\",\n        \"arguments\": {\n          \"${username}\": \"demo\",\n          \"${password}\": \"${EMPTY}\"\n        },\n        \"tags\": [\n          \"1\"\n        ],\n        \"documentation\": \"This is a test case documentation of the first one.\"\n      },\n      {\n        \"test_case_name\": \"Right user wrong pass\",\n        \"arguments\": {\n          \"${username}\": \"demo\",\n          \"${password}\": \"FooBar\"\n        },\n        \"tags\": [\n          \"2\",\n          \"3\",\n          \"foo\"\n        ],\n        \"documentation\": \"This test case has the Tags 2,3 and foo\"\n      },\n      {\n        \"test_case_name\": \"Login with user '${EMPTY}' and password 'mode'\",\n        \"arguments\": {\n          \"${username}\": \"${EMPTY}\",\n          \"${password}\": \"mode\"\n        },\n        \"tags\": [\n          \"1\",\n          \"2\",\n          \"3\",\n          \"4\"\n        ],\n        \"documentation\": \"This test case has a generated name based on template name.\"\n      },\n      {\n        \"test_case_name\": \"Login with user '${EMPTY}' and password '${EMPTY}'\",\n        \"arguments\": {\n          \"${username}\": \"${EMPTY}\",\n          \"${password}\": \"${EMPTY}\"\n        },\n        \"tags\": [\n          \"\"\n        ],\n        \"documentation\": \"\"\n      },\n      {\n        \"test_case_name\": \"Login with user '${EMPTY}' and password 'FooBar'\",\n        \"arguments\": {\n          \"${username}\": \"${EMPTY}\",\n          \"${password}\": \"FooBar\"\n        },\n        \"tags\": [\n          \"\"\n        ],\n        \"documentation\": \"\"\n      },\n      {\n        \"test_case_name\": \"Login with user 'FooBar' and password 'mode'\",\n        \"arguments\": {\n          \"${username}\": \"FooBar\",\n          \"${password}\": \"mode\"\n        },\n        \"tags\": [\n          \"foo\",\n          \"1\"\n        ],\n        \"documentation\": \"\"\n      },\n      {\n        \"test_case_name\": \"Login with user 'FooBar' and password '${EMPTY}'\",\n        \"arguments\": {\n          \"${username}\": \"FooBar\",\n          \"${password}\": \"${EMPTY}\"\n        },\n        \"tags\": [\n          \"foo\"\n        ],\n        \"documentation\": \"\"\n      },\n      {\n        \"test_case_name\": \"Login with user 'FooBar' and password 'FooBar'\",\n        \"arguments\": {\n          \"${username}\": \"FooBar\",\n          \"${password}\": \"FooBar\"\n        },\n        \"tags\": [\n          \"foo\",\n          \"2\"\n        ],\n        \"documentation\": \"\"\n      }\n    ]\n\nThis can be accessed as usual in Robot Framework®.\n\n``${DataDriver_DATA_LIST}[2][arguments][\\\\${password}]`` would result in ``mode`` .\n\n\n\n\u0026{DataDriver_DATA_DICT}\n~~~~~~~~~~~~~~~~~~~~~~~\n\nA dictionary as suite variable that contains the same data as the list, with the test names as keys.\n\n.. code :: json\n\n    {\n      \"Right user empty pass\": {\n        \"test_case_name\": \"Right user empty pass\",\n        \"arguments\": {\n          \"${username}\": \"demo\",\n          \"${password}\": \"${EMPTY}\"\n        },\n        \"tags\": [\n          \"1\"\n        ],\n        \"documentation\": \"This is a test case documentation of the first one.\"\n      },\n      \"Right user wrong pass\": {\n        \"test_case_name\": \"Right user wrong pass\",\n        \"arguments\": {\n          \"${username}\": \"demo\",\n          \"${password}\": \"FooBar\"\n        },\n        \"tags\": [\n          \"2\",\n          \"3\",\n          \"foo\"\n        ],\n        \"documentation\": \"This test case has the Tags 2,3 and foo\"\n      },\n      \"Login with user '${EMPTY}' and password 'mode'\": {\n        \"test_case_name\": \"Login with user '${EMPTY}' and password 'mode'\",\n        \"arguments\": {\n          \"${username}\": \"${EMPTY}\",\n          \"${password}\": \"mode\"\n        },\n        \"tags\": [\n          \"1\",\n          \"2\",\n          \"3\",\n          \"4\"\n        ],\n        \"documentation\": \"This test case has a generated name based on template name.\"\n      },\n      \"Login with user '${EMPTY}' and password '${EMPTY}'\": {\n        \"test_case_name\": \"Login with user '${EMPTY}' and password '${EMPTY}'\",\n        \"arguments\": {\n          \"${username}\": \"${EMPTY}\",\n          \"${password}\": \"${EMPTY}\"\n        },\n        \"tags\": [\n          \"\"\n        ],\n        \"documentation\": \"\"\n      },\n      \"Login with user '${EMPTY}' and password 'FooBar'\": {\n        \"test_case_name\": \"Login with user '${EMPTY}' and password 'FooBar'\",\n        \"arguments\": {\n          \"${username}\": \"${EMPTY}\",\n          \"${password}\": \"FooBar\"\n        },\n        \"tags\": [\n          \"\"\n        ],\n        \"documentation\": \"\"\n      },\n      \"Login with user 'FooBar' and password 'mode'\": {\n        \"test_case_name\": \"Login with user 'FooBar' and password 'mode'\",\n        \"arguments\": {\n          \"${username}\": \"FooBar\",\n          \"${password}\": \"mode\"\n        },\n        \"tags\": [\n          \"foo\",\n          \"1\"\n        ],\n        \"documentation\": \"\"\n      },\n      \"Login with user 'FooBar' and password '${EMPTY}'\": {\n        \"test_case_name\": \"Login with user 'FooBar' and password '${EMPTY}'\",\n        \"arguments\": {\n          \"${username}\": \"FooBar\",\n          \"${password}\": \"${EMPTY}\"\n        },\n        \"tags\": [\n          \"foo\"\n        ],\n        \"documentation\": \"\"\n      },\n      \"Login with user 'FooBar' and password 'FooBar'\": {\n        \"test_case_name\": \"Login with user 'FooBar' and password 'FooBar'\",\n        \"arguments\": {\n          \"${username}\": \"FooBar\",\n          \"${password}\": \"FooBar\"\n        },\n        \"tags\": [\n          \"foo\",\n          \"2\"\n        ],\n        \"documentation\": \"\"\n      }\n    }\n\n\u0026{DataDriver_TEST_DATA}\n~~~~~~~~~~~~~~~~~~~~~~~\n\nA dictionary as test variable that contains the test data of the current test case.\nThis dictionary does also contain arguments that are not used in the ``Test Template`` keyword.\nThis can be used in Test Setup and within a test case.\n\n.. code :: json\n\n    {\n      \"test_case_name\": \"Right user wrong pass\",\n      \"arguments\": {\n        \"${username}\": \"demo\",\n        \"${password}\": \"FooBar\"\n      },\n      \"tags\": [\n        \"2\",\n        \"3\",\n        \"foo\"\n      ],\n      \"documentation\": \"This test case has the Tags 2,3 and foo\"\n    }\n\n\nData Sources\n------------\n\n\nCSV / TSV (Character-separated values)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nBy default DataDriver reads csv files. With the `Encoding and CSV\nDialect \u003c#file-encoding-and-csv-dialect\u003e`__ settings you may configure which\nstructure your data source has.\n\n\nXLS / XLSX Files\n~~~~~~~~~~~~~~~~\n\nTo use Excel file types, you have to install DataDriver with the Extra XLS.\n\nIf you want to use Excel based data sources, you may just set the file\nto the extention or you may point to the correct file. If the extention\nis \".xls\" or \".xlsx\" DataDriver will interpret it as Excel file.\nYou may select the sheet which will be read by the option ``sheet_name``.\nBy default it is set to 0 which will be the first table sheet.\nYou may use sheet index (0 is first sheet) or sheet name(case sensitive).\nXLS interpreter will ignore all other options like encoding, delimiters etc.\n\n.. code :: robotframework\n\n    *** Settings ***\n    Library    DataDriver    .xlsx\n\nor:\n\n.. code :: robotframework\n\n    *** Settings ***\n    Library    DataDriver    file=my_data_source.xlsx    sheet_name=2nd Sheet\n\n\nMS Excel and typed cells\n^^^^^^^^^^^^^^^^^^^^^^^^\n\nMicrosoft Excel xls or xlsx file have the possibility to type thair data\ncells. Numbers are typically of the type float. If these data are not\nexplicitly defined as text in Excel, pandas will read it as the type\nthat is has in excel. Because we have to work with strings in Robot\nFramework® these data are converted to string. This leads to the\nsituation that a European time value like \"04.02.2019\" (4th January\n2019) is handed over to Robot Framework® in Iso time \"2019-01-04\n00:00:00\". This may cause unwanted behavior. To mitigate this risk you\nshould define Excel based files explicitly as text within Excel.\n\nAlternatively you may deactivate that string conversion.\nTo do so, you have to add the option ``preserve_xls_types`` to ``True``.\nIn that case, you will get str, float, boolean, int, datetime.time,\ndatetime.datetime and some others.\n\n.. code :: robotframework\n\n    *** Settings ***\n    Library    DataDriver    file=my_data_source.xlsx    preserve_xls_types=True\n\nPICT (Pairwise Independent Combinatorial Testing)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nPict is able to generate data files based on a model file.\nhttps://github.com/Microsoft/pict\n\nDocumentation: https://github.com/Microsoft/pict/blob/master/doc/pict.md\n\n\nRequirements of PICT\n^^^^^^^^^^^^^^^^^^^^\n\n-  Path to pict.exe must be set in the %PATH% environment variable.\n-  Data model file has the file extention \".pict\"\n-  Pict model file must be encoded in UTF-8\n\n\nHow it works\n^^^^^^^^^^^^\n\nIf the file option is set to a file with the extention pict, DataDriver\nwill hand over this file to pict.exe and let it automatically generates\na file with the extention \".pictout\". This file will the be used as data\nsource for the test generation. (It is tab seperated and UTF-8 encoded)\nExcept the file option all other options of the library will be ignored.\n\n.. code :: robotframework\n\n    *** Settings ***\n    Library    DataDriver    my_model_file.pict\n\nIt is possible to give options to pict with the import argument `pict_options=`.\n\n.. code :: robotframework\n\n    *** Settings ***\n    Library    DataDriver    pict_arg.pict    pict_options=/o:3 /r\n\n\nGlob File Pattern\n~~~~~~~~~~~~~~~~~\n\nThis module implements a reader class that creates a test case for each file or folder that matches the given glob pattern.\n\nWith an optional argument \"arg_name\" you can modify the argument that will be set. See folder example.\n\nExample with json files:\n\n.. code :: robotframework\n\n    *** Settings ***\n    Library           DataDriver    file=${CURDIR}/DataFiles/*_File.json    reader_class=glob_reader\n    Library           OperatingSystem\n    Test Template     Test all Files\n\n\n    *** Test Cases ***\n    Glob_Reader_Test    Wrong_File.NoJson\n\n\n    *** Keywords ***\n    Test all Files\n        [Arguments]    ${file_name}\n        ${file_content}=    Get File    ${file_name}\n        ${content}=    Evaluate    json.loads($file_content)[\"test_case\"]\n        Should Be Equal    ${TEST_NAME}    ${content}\n\n\nExample with folders:\n\n.. code :: robotframework\n\n    *** Settings ***\n    Library           DataDriver    file=${CURDIR}/FoldersToFind/*/    reader_class=glob_reader    arg_name=\\\\${folder_name}\n    Library           OperatingSystem\n    Test Template     Test all Files\n\n\n    *** Test Cases ***\n    Glob_Reader_Test    Wrong_File.NoJson\n\n\n    *** Keywords ***\n    Test all Files\n        [Arguments]    ${folder_name}\n        ${content}=    Get File    ${folder_name}/verify.txt\n        Should Be Equal    ${TEST_NAME}    ${content}\n\n\nFile Encoding and CSV Dialect\n-----------------------------\n\nWhile there are various specifications and implementations for the CSV format\n(see `RFC 4180 \u003chttps://www.rfc-editor.org/rfc/rfc4180.html\u003e`_),\nthere is no formal specification in existence, which allows for a wide variety of interpretations of CSV files.\nTherefore it is possible to define your own dialect or use\npredefined. The default is Excel-EU which is a semicolon separated\nfile.\nThese Settings are changeable as options of the Data Driver Library.\n\n\nfile=\n~~~~~\n\n.. code :: robotframework\n\n    *** Settings ***\n    Library         DataDriver    file=../data/my_data_source.csv\n\n\n-  None(default): Data Driver will search in the test suites folder if a\n   \\*.csv file with the same name than the test suite \\*.robot file exists\n-  only file extention: if you just set a file extentions like \".xls\" or\n   \".xlsx\" DataDriver will search\n-  absolute path: If an absolute path to a file is set, DataDriver tries\n   to find and open the given data file.\n-  relative path: If the option does not point to a data file as an\n   absolute path, Data Driver tries to find a data file relative to the\n   folder where the test suite is located.\n\n\nencoding=\n~~~~~~~~~\n\n``encoding=`` must be set if it shall not be cp1252.\n\n**Examples**:\n\n``cp1252, ascii, iso-8859-1, latin-1, utf_8, utf_16, utf_16_be, utf_16_le``\n\n**cp1252** is:\n\n- Code Page 1252\n- Windows-1252\n- Windows Western European\n\nMost characters are same between ISO-8859-1 (Latin-1) except for the code points 128-159 (0x80-0x9F).\nThese Characters are available in cp1252 which are not present in Latin-1.\n\n``€ ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ Ž ‘ ’ “ ” • – — ˜ ™ š › œ ž Ÿ``\n\nSee `Python Standard Encoding \u003chttps://docs.python.org/3/library/codecs.html#standard-encodings\u003e`_ for more encodings\n\n\ndialect=\n~~~~~~~~\n\nYou may change the CSV Dialect here.\nThe dialect option can be one of the following:\n- Excel-EU\n- excel\n- excel-tab\n- unix\n- UserDefined\n\nsupported Dialects are:\n\n.. code:: python\n\n    \"Excel-EU\"\n        delimiter=';',\n        quotechar='\"',\n        escapechar='\\\\',\n        doublequote=True,\n        skipinitialspace=False,\n        lineterminator=\"\\\\r\\\\n\",\n        quoting=csv.QUOTE_ALL\n\n    \"excel\"\n        delimiter = ','\n        quotechar = '\"'\n        doublequote = True\n        skipinitialspace = False\n        lineterminator = '\\\\r\\\\n'\n        quoting = QUOTE_MINIMAL\n\n    \"excel-tab\"\n        delimiter = '\\\\t'\n        quotechar = '\"'\n        doublequote = True\n        skipinitialspace = False\n        lineterminator = '\\\\r\\\\n'\n        quoting = QUOTE_MINIMAL\n\n    \"unix\"\n        delimiter = ','\n        quotechar = '\"'\n        doublequote = True\n        skipinitialspace = False\n        lineterminator = '\\\\n'\n        quoting = QUOTE_ALL\n\n\n\n\nUsage in Robot Framework®\n\n.. code :: robotframework\n\n    *** Settings ***\n    Library    DataDriver    my_data_file.csv    dialect=excel\n\n\n\n.. code :: robotframework\n\n    *** Settings ***\n    Library    DataDriver    my_data_file.csv    dialect=excel_tab\n\n\n\n.. code :: robotframework\n\n    *** Settings ***\n    Library    DataDriver    my_data_file.csv    dialect=unix_dialect\n\n\n\nExample User Defined\n^^^^^^^^^^^^^^^^^^^^\n\nUser may define the format completely free.\nIf an option is not set, the default values are used.\nTo register a userdefined format user have to set the\noption ``dialect`` to ``UserDefined``\n\n\nUsage in Robot Framework®\n\n.. code :: robotframework\n\n    *** Settings ***\n    Library    DataDriver    my_data_file.csv\n    ...    dialect=UserDefined\n    ...    delimiter=.\n    ...    lineterminator=\\\\n\n\n\n\n\nDefaults:\n~~~~~~~~~\n\n.. code:: python\n\n    file=None,\n    encoding='cp1252',\n    dialect='Excel-EU',\n    delimiter=';',\n    quotechar='\"',\n    escapechar='\\\\\\\\',\n    doublequote=True,\n    skipinitialspace=False,\n    lineterminator='\\\\r\\\\n',\n    sheet_name=0\n\n\nCustom DataReader Classes\n-------------------------\n\nIt is possible to write your own DataReader Class as a plugin for DataDriver.\nDataReader Classes are called from DataDriver to return a list of TestCaseData.\n\n\nUsing Custom DataReader\n~~~~~~~~~~~~~~~~~~~~~~~\n\nDataReader classes are loaded dynamically into DataDriver while runtime.\nDataDriver identifies the DataReader to load by the file extantion of the data file or by the option ``reader_class``.\n\n\nSelect Reader by File Extension:\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. code :: robotframework\n\n    *** Settings ***\n    Library    DataDriver    file=mydata.csv\n\nThis will load the class ``csv_reader`` from ``csv_reader.py`` from the same folder.\n\n\nSelect Reader by Option:\n^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. code :: robotframework\n\n    *** Settings ***\n        Library    DataDriver   file=mydata.csv    reader_class=generic_csv_reader    dialect=userdefined   delimiter=\\\\t    encoding=UTF-8\n\nThis will load the class ``generic_csv_reader`` from ``generic_csv_reader.py`` from same folder.\n\n\nCreate Custom Reader\n~~~~~~~~~~~~~~~~~~~~\n\nRecommendation:\n\nHave a look to the Source Code of existing DataReader like ``csv_reader.py`` or ``generic_csv_reader.py`` .\n\nTo write your own reader, create a class inherited from ``AbstractReaderClass``.\n\nYour class will get all available configs from DataDriver as an object of ``ReaderConfig`` on ``__init__``.\n\nDataDriver will call the method ``get_data_from_source``\nThis method should then load your data from your custom source and stores them into list of object of ``TestCaseData``.\nThis List of ``TestCaseData`` will be returned to DataDriver.\n\n``AbstractReaderClass`` has also some optional helper methods that may be useful.\n\nYou can either place the custom reader with the others in DataDriver folder or anywhere on the disk.\nIn the first case or if your custom reader is in python path just use it like the others by name:\n\n.. code :: robotframework\n\n    *** Settings ***\n    Library          DataDriver    reader_class=my_reader\n\nIn case it is somewhere on the disk, it is possible to use an absolute or relative path to a custom Reader.\nImports of custom readers follow the same rules like importing Robot Framework® libraries.\nPath can be relative to ${EXECDIR} or to DataDriver/__init__.py:\n\n\n.. code :: robotframework\n\n    *** Settings ***\n    Library          DataDriver    reader_class=C:/data/my_reader.py    # set custom reader\n    ...                            file_search_strategy=None            # set DataDriver to not check file\n    ...                            min=0                                # kwargs arguments for custom reader\n    ...                            max=62\n\nThis `my_reader.py` should implement a class inherited from AbstractReaderClass that is named `my_reader`.\n\n.. code :: python\n\n    from DataDriver.AbstractReaderClass import AbstractReaderClass  # inherit class from AbstractReaderClass\n    from DataDriver.ReaderConfig import TestCaseData  # return list of TestCaseData to DataDriver\n\n\n    class my_reader(AbstractReaderClass):\n\n        def get_data_from_source(self):  # This method will be called from DataDriver to get the TestCaseData list.\n            test_data = []\n            for i in range(int(self.kwargs['min']), int(self.kwargs['max'])):  # Dummy code to just generate some data\n                args = {'${var_1}': str(i), '${var_2}': str(i)}  # args is a dictionary. Variable name is the key, value is value.\n                test_data.append(TestCaseData(f'test {i}', args, ['tag']))  # add a TestCaseData object to the list of tests.\n            return test_data  # return the list of TestCaseData to DataDriver\n\n\nSee other readers as example.\n\n\nSelection of Test Cases to Execute\n----------------------------------\n\nBecause test cases that are created by DataDriver after parsing while execution,\nit is not possible to use some Robot Framework® methods to select test cases.\n\n\nExamples for options that have to be used differently:\n\n+-------------------+-----------------------------------------------------------------------+\n| robot option      | Description                                                           |\n+===================+=======================================================================+\n| ``--test``        | Selects the test cases by name.                                       |\n+-------------------+-----------------------------------------------------------------------+\n| ``--task``        | Alias for --test that can be used when executing tasks.               |\n+-------------------+-----------------------------------------------------------------------+\n| ``--rerunfailed`` | Selects failed tests from an earlier output file to be re-executed.   |\n+-------------------+-----------------------------------------------------------------------+\n| ``--include``     | Selects the test cases by tag.                                        |\n+-------------------+-----------------------------------------------------------------------+\n| ``--exclude``     | Selects the test cases by tag.                                        |\n+-------------------+-----------------------------------------------------------------------+\n\n\nSelection of test cases by name\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n\nSelect a single test case:\n^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTo execute just a single test case by its exact name it is possible to execute the test suite\nand set the global variable ${DYNAMICTEST} with the name of the test case to execute as value.\nPattern must be ``suitename.testcasename``.\n\nExample:\n\n.. code ::\n\n    robot --variable \"DYNAMICTEST:my suite name.test case to be executed\" my_suite_name.robot\n\nPabot uses this feature to execute a single test case when using ``--testlevelsplit``\n\n\nSelect a list of test cases:\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIt is possible to set a list of test case names by using the variable ${DYNAMICTESTS} (plural).\nThis variable must be a string and the list of names must be pipe-seperated (``|``).\n\nExample:\n\n.. code::\n\n    robot --variable DYNAMICTESTS:firstsuitename.testcase1|firstsuitename.testcase3|anothersuitename.othertestcase foldername\n\nIt is also possible to set the variable @{DYNAMICTESTS} as a list variable from i.e. python code.\n\n\nRe-run failed test cases:\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\nBecause it is not possible to use the command line argument ``--rerunfailed`` from robot directly,\nDataDriver brings a Pre-Run-Modifier that handles this issue.\n\nNormally reexecution of failed testcases has three steps.\n\n- original execution\n- re-execution the failed ones based on original execution output\n- merging original execution output with re-execution output\n\nThe DataDriver.rerunfailed Pre-Run-Modifier removes all passed test cases based on a former output.xml.\n\nExample:\n\n.. code ::\n\n    robot --output original.xml tests                                                    # first execute all tests\n    robot --prerunmodifier DataDriver.rerunfailed:original.xml --output rerun.xml tests  # then re-execute failing\n    rebot --merge original.xml rerun.xml                                                 # finally merge results\n\n\nBe aware, that in this case it is not allowed to use \"``:``\" as character in the original output file path.\nIf you want to set a full path on windows like ``e:\\\\myrobottest\\\\output.xml`` you have to use \"``;``\"\nas argument seperator.\n\nExample:\n\n.. code ::\n\n    robot --prerunmodifier DataDriver.rerunfailed;e:\\\\myrobottest\\\\output.xml --output e:\\\\myrobottest\\\\rerun.xml tests\n\n\n\nFiltering with tags.\n~~~~~~~~~~~~~~~~~~~~\n\nNew in ``0.3.1``\n\nIt is possible to use tags to filter the data source.\nTo use this, tags must be assigned to the test cases in data source.\n\n\nRobot Framework® Command Line Arguments\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTo filter the source, the normal command line arguments of Robot Framework® can be used.\nSee Robot Framework® Userguide_ for more information\nBe aware that the filtering of Robot Framework® itself is done before DataDriver is called.\nThis means if the Template test is already filtered out by Robot Framework®, DataDriver can never be called.\nIf you want to use ``--include`` the DataDriver TestSuite should have a ``DefaultTag`` or ``ForceTag`` that\nfulfills these requirements.\n\n.. _Userguide: https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#tag-patterns\n\nExample: ``robot --include 1OR2 --exclude foo DataDriven.robot``\n\n\nFilter based on Library Options\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIt is also possible to filter the data source by an init option of DataDriver.\nIf these Options are set, Robot Framework® Filtering will be ignored.\n\nExample:\n\n.. code :: robotframework\n\n    *** Settings ***\n    Library    DataDriver    include=1OR2    exclude=foo\n\n\n\n\nConfigure DataDriver by Pre-Run Keyword\n---------------------------------------\n\nWith ``config_keyword=`` it's possible to name a keyword that will be called from Data Driver before it starts the actual processing of the ``data file``.\nOne possible usage is if the ``data file`` itself shall be created by another keyword dynamically during the execution of the Data Driver test suite.\nThe ``config_keyword=`` can be used to call that keyword and return the updated arguments (e.g. ``file``) back to the Data Driver Library.\n\nThe ``config keyword``\n\n- May be defined globally or inside each testsuite individually\n- Gets all the arguments, that Data Driver gets from Library import, as a Robot Dictionary\n- Shall return the (updated) Data Driver arguments as a Robot Dictionary\n\nUsage in Robot Framework®\n\n.. code :: robotframework\n\n    *** Settings ***\n    Library           OperatingSystem\n    Library           DataDriver    dialect=excel    encoding=utf_8   config_keyword=Config\n    Test Template     The Keyword\n\n    *** Test Cases ***\n    Test    aaa\n\n    *** Keywords ***\n    The Keyword\n        [Arguments]    ${var}\n        Log To Console    ${var}\n\n    Config\n        [Arguments]    ${original_config}\n        Log To Console    ${original_config.dialect}                # just a log of the original\n        Create File    ${CURDIR}/test321.csv\n        ...    *** Test Cases ***,\\\\${var},\\\\n123,111,\\\\n321,222,      # generating file\n        ${new_config}=    Create Dictionary    file=test321.csv     # set file attribute in a dictionary\n        [Return]    ${new_config}                                   # returns {'file': 'test321.csv'}\n\n\n\nPabot and DataDriver\n--------------------\n\nYou should use Pabot version 1.10.0 or newer.\n\nDataDriver supports ``--testlevelsplit`` from pabot only if the PabotLib is in use.\nUse ``--pabotlib`` to enable that.\n\nWhen using pabot like this, DataDriver automatically splits the amount of test cases into nearly same sized groups.\nIs uses the processes count from pabot to calculate the groups.\nWhen using 8 processes with 100 test cases you will get 8 groups of tests with the size of 12 to 13 tests.\nThese 8 groups are then executed as one block with 8 processes.\nThis reduces a lot of overhead with Suite Setup and Teardown.\n\nYou can switch between three modes:\n\n- ``Equal``: means it creates equal sizes groups\n- ``Binary``: is more complex. it created a decreasing size of containers to support better balancing.\n- ``Atomic``: it does not group tests at all and runs really each test case in a separate thread.\n\nThis can be set by ``optimize_pabot`` in Library import.\n\n\n**Example**:\n\n.. code :: robotframework\n\n    *** Settings ***\n    Library          DataDriver    optimize_pabot=Binary\n\nBinary creates with 40 test cases and 8 threads something like that:\n\n.. code ::\n\n    P01: 01,02,03,04,05\n    P02: 06,07,08,09,10\n    P03: 11,12,13,14,15\n    P04: 16,17,18,19,20\n    P05: 21,22,23\n    P06: 24,25,26\n    P07: 27,28,29\n    P08: 30,31,32\n    P09: 33\n    P10: 34\n    P11: 35\n    P12: 36\n    P13: 37\n    P14: 38\n    P15: 39\n    P16: 40","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnooz82%2Frobotframework-datadriver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsnooz82%2Frobotframework-datadriver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnooz82%2Frobotframework-datadriver/lists"}