# RoboMachine
A test data generator for [Robot Framework](http://www.robotframework.org).
## What is this tool for?
You know those ugly bugs that users report that somehow were missed by all your ATDD-, TDD- and exploratory testing? Those bugs that lurk in the corners of complexity of the system that you are building. Those bugs that will make users of your application hate you..
This tool is here to help you seek and destroy those bugs before users will find them.
It gives you the ability to generate a huge number of tests that can go through a very vast number of similar (or not so similar) test scenarios.
## What is it?
If you know Regular Expressions:
A regular expression is a pattern that represents all the possible strings that match that pattern. RoboMachine works in a similar way. A machine represents a set of tests in a compact way. This machine can be used to generate all (or part of) the tests that it represents.
If you know Model-Based Testing or automata theory:
With RoboMachine you define an extended finite state machine (in a Robot Framework -like syntax) that represents a set of tests. RoboMachine also contains algorithms that can be used to generate real executable Robot Framework tests from a RoboMachine model.
If you know Combinatorial Testing or like data driven testing:
With RoboMachine you can define sets of data and rules about that data, that can be used to generate data driven tests (and also keyword driven tests). This allows you to keep your data in compact sets and let the system generate the real test data vectors from there.
## What does it look like?
Here is an example machine (using combinatorial techniques) that can generate tests for [SeleniumLibrary demo](http://code.google.com/p/robotframework-seleniumlibrary/wiki/Demo).
```robotframework
*** Settings ***
Suite Setup Open Browser ${LOGIN_PAGE_URL} googlechrome
Suite Teardown Close Browser
Test Setup Go to ${LOGIN_PAGE_URL}
Library SeleniumLibrary
*** Variables ***
${USERNAME_FIELD} username_field
${PASSWORD_FIELD} password_field
${LOGIN_BUTTON} LOGIN
${VALID_USERNAME} demo
${VALID_PASSWORD} mode
${LOGIN_PAGE_URL} http://localhost:7272/html/
*** Machine ***
${USERNAME} any of ${VALID_USERNAME} ${VALID_PASSWORD} invalid123 ${EMPTY}
${PASSWORD} any of ${VALID_PASSWORD} ${VALID_USERNAME} password123 ${EMPTY}
# Add an equivalence rule to reduce the number of generated tests
${USERNAME} == ${VALID_PASSWORD} <==> ${PASSWORD} == ${VALID_USERNAME}
Login Page
Title Should Be Login Page
[Actions]
Submit Credentials ==> Welcome Page when ${USERNAME} == ${VALID_USERNAME} and ${PASSWORD} == ${VALID_PASSWORD}
Submit Credentials ==> Error Page otherwise
Welcome Page
Title Should Be Welcome Page
Error Page
Title Should Be Error Page
*** Keywords ***
Submit Credentials
Input Text ${USERNAME_FIELD} ${USERNAME}
Input Password ${PASSWORD_FIELD} ${PASSWORD}
Click Button ${LOGIN_BUTTON}
```
Here is another example machine (using model-based testing with finite state machine):
```robotframework
*** Settings ***
Suite Setup Open Browser ${LOGIN_PAGE_URL} googlechrome
Suite Teardown Close Browser
Test Setup Go to ${LOGIN_PAGE_URL}
Library SeleniumLibrary
*** Variables ***
${USERNAME_FIELD} username_field
${PASSWORD_FIELD} password_field
${LOGIN_BUTTON} LOGIN
${VALID_USERNAME} demo
${VALID_PASSWORD} mode
${LOGIN_PAGE_URL} http://localhost:7272/html/
*** Machine ***
Login Page
Title Should Be Login Page
[Actions]
Submit Valid Credentials ==> Welcome Page
Submit Invalid Credentials ==> Error Page
Welcome Page
Title Should Be Welcome Page
[Actions]
Go to ${LOGIN_PAGE_URL} ==> Login Page
Error Page
Title Should Be Error Page
[Actions]
Go to ${LOGIN_PAGE_URL} ==> Login Page
*** Keywords ***
Submit Valid Credentials
Submit Credentials ${VALID_USERNAME} ${VALID_PASSWORD}
Submit Invalid Credentials
Submit Credentials invalid_username invalid_password
Submit Credentials
[Arguments] ${username} ${password}
Input Text ${USERNAME_FIELD} ${USERNAME}
Input Password ${PASSWORD_FIELD} ${PASSWORD}
Click Button ${LOGIN_BUTTON}
```
NOTE! This machine can generate infinite number of test sequences thus you need to constraint the generation.
For example:
robomachine --tests-max 10 --actions-max 20 --to-state 'Welcome Page' --generation-algorithm random [MACHINE_FILE_NAME]
will generate 10 random tests with at most 20 actions each and all tests ending to state 'Welcome Page'.
## Installation
From [Python Package Index](http://pypi.python.org/pypi)
pip install RoboMachine
From source:
git clone git://github.com/mkorpela/RoboMachine.git
cd RoboMachine
python setup.py install
After this you should have a commandline tool called `robomachine` available.
See `robomachine --help` for commandline tool usage.
## Syntax
* Only supported Robot Framework format is space separated format.
* You should use `.robomachine` suffix for your Machine files.
* You can have a Robot Framework *Settings* table at the beginning of the machine file.
* You can have a Robot Framework *Variables* table after the optional Settings table.
* *Machine* table is a must.
* You can have a Robot Framework *Keywords* table after the Machine table.
## Machine table syntax
Used machine variables must be introduced at the beginning of the machine table. Valid machine variable is a valid Robot Framework variable that contains only uppercase characters A-Z, numbers (not at the start) 0-9 and
underscores (`_`). For example: `${VALID_123}` is a valid machine variable.
An example of a valid machine variable definition line::
${VALID_VARIABLE_1} any of Value 1 Value 2 Value 3
Rules about the machine variables should be next. Rule building blocks:
* Variable conditions:
* `${VARIABLE} == value`
* `${VARIABLE} != value`
* `${VARIABLE} < value`
* `${VARIABLE} <= value`
* `${VARIABLE} > value`
* `${VARIABLE} >= value`
* `${VARIABLE} in (a, b)` # short for ${VARIABLE} == a or ${VARIABLE} == b
* `${VARIABLE} ~ REGEX` # python regexp: re.search(REGEX, ${VARIABLE}) != None
* `${VARIABLE} !~ REGEX` # negated regexp match
* And rule: [some condition] and [some other condition]
* Or rule: [some condition] or [some other condition]
* Not rule: not ([some condition])
* Implication rule: [some condition] ==> [some condition]
* Equivalence rule: [some condition] <==> [some condition]
* [some condition]: Variable condition OR (rule)
Rules can be used to remove variable combinations that should not be used in
test generation.
An example of a valid rule line:
${VARIABLE_1} == Value 1 ==> (${FOO} == bar or ${FOO} == zoo)
Which means: When `${VARIABLE_1}` value is "Value 1" then `${FOO}` should either be "bar" or "zoo".
State blocks should be next. First state block is the starting state.
State block starts with a line containing the states name. Valid state name contains only upper and lowercase characters a-zA-Z, numbers (not at the start) 0-9 and spaces (not at the start or end and only one
between words).
This is followed by the Robot Framework steps that should be executed when in that
state.
This can be followed by an actions block definition.
An actions block starts with `[Actions]` tag and is followed by one or more action lines.
An action line has four parts:
* A Robot Framework step that is executed when the action happens (action label) (you can also leave this out - use a tau transition)
* ` ==> ` right arrow with two spaces before and after
* Name of the state that the machine ends up when the action is taken (end state)
* Optional rule (when the action is available) this either starts with
` when ` and the rule or ` otherwise ` - meaning this action should be taken when
all of the other actions with same action label are not available
An example of a valid state definition::
```robotframework
State Name
Robot Framework Step with ${arguments}
Log something WARN
[Actions]
Log other thing ==> Other State when ${FOO} == bar
Log other thing ==> Another State when (${FOO} == zoo and ${BAR} == goo)
Log other thing ==> End State otherwise
Log nothing ==> End State
==> Some state # This here is a tau transition that does not write a step to the test
```
Raw data
{
"_id": null,
"home_page": "https://github.com/mkorpela/RoboMachine",
"name": "RoboMachine",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": "",
"keywords": "",
"author": "Mikko Korpela",
"author_email": "mikko.korpela@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/c6/cd/d3de0a099abeb4ca51497ef9a4c4d875ea0c401b2915fc3f6ec031fadefd/RoboMachine-0.10.0.tar.gz",
"platform": null,
"description": "# RoboMachine\n\nA test data generator for [Robot Framework](http://www.robotframework.org).\n\n## What is this tool for?\n\nYou know those ugly bugs that users report that somehow were missed by all your ATDD-, TDD- and exploratory testing? Those bugs that lurk in the corners of complexity of the system that you are building. Those bugs that will make users of your application hate you..\n\nThis tool is here to help you seek and destroy those bugs before users will find them.\n\nIt gives you the ability to generate a huge number of tests that can go through a very vast number of similar (or not so similar) test scenarios.\n\n## What is it?\n\nIf you know Regular Expressions:\nA regular expression is a pattern that represents all the possible strings that match that pattern. RoboMachine works in a similar way. A machine represents a set of tests in a compact way. This machine can be used to generate all (or part of) the tests that it represents.\n\nIf you know Model-Based Testing or automata theory:\nWith RoboMachine you define an extended finite state machine (in a Robot Framework -like syntax) that represents a set of tests. RoboMachine also contains algorithms that can be used to generate real executable Robot Framework tests from a RoboMachine model.\n\nIf you know Combinatorial Testing or like data driven testing:\nWith RoboMachine you can define sets of data and rules about that data, that can be used to generate data driven tests (and also keyword driven tests). This allows you to keep your data in compact sets and let the system generate the real test data vectors from there.\n\n## What does it look like?\n\nHere is an example machine (using combinatorial techniques) that can generate tests for [SeleniumLibrary demo](http://code.google.com/p/robotframework-seleniumlibrary/wiki/Demo).\n\n```robotframework\n*** Settings ***\nSuite Setup Open Browser ${LOGIN_PAGE_URL} googlechrome\nSuite Teardown Close Browser\nTest Setup Go to ${LOGIN_PAGE_URL}\nLibrary SeleniumLibrary\n\n*** Variables ***\n${USERNAME_FIELD} username_field\n${PASSWORD_FIELD} password_field\n${LOGIN_BUTTON} LOGIN\n${VALID_USERNAME} demo\n${VALID_PASSWORD} mode\n${LOGIN_PAGE_URL} http://localhost:7272/html/\n\n*** Machine ***\n${USERNAME} any of ${VALID_USERNAME} ${VALID_PASSWORD} invalid123 ${EMPTY}\n${PASSWORD} any of ${VALID_PASSWORD} ${VALID_USERNAME} password123 ${EMPTY}\n\n# Add an equivalence rule to reduce the number of generated tests\n${USERNAME} == ${VALID_PASSWORD} <==> ${PASSWORD} == ${VALID_USERNAME}\n\nLogin Page\n Title Should Be Login Page\n [Actions]\n Submit Credentials ==> Welcome Page when ${USERNAME} == ${VALID_USERNAME} and ${PASSWORD} == ${VALID_PASSWORD}\n Submit Credentials ==> Error Page otherwise\n\nWelcome Page\n Title Should Be Welcome Page\n\nError Page\n Title Should Be Error Page\n\n*** Keywords ***\nSubmit Credentials\n Input Text ${USERNAME_FIELD} ${USERNAME}\n Input Password ${PASSWORD_FIELD} ${PASSWORD}\n Click Button ${LOGIN_BUTTON}\n```\n\nHere is another example machine (using model-based testing with finite state machine):\n\n```robotframework\n*** Settings ***\nSuite Setup Open Browser ${LOGIN_PAGE_URL} googlechrome\nSuite Teardown Close Browser\nTest Setup Go to ${LOGIN_PAGE_URL}\nLibrary SeleniumLibrary\n\n*** Variables ***\n${USERNAME_FIELD} username_field\n${PASSWORD_FIELD} password_field\n${LOGIN_BUTTON} LOGIN\n${VALID_USERNAME} demo\n${VALID_PASSWORD} mode\n${LOGIN_PAGE_URL} http://localhost:7272/html/\n\n*** Machine ***\nLogin Page\n Title Should Be Login Page\n [Actions]\n Submit Valid Credentials ==> Welcome Page\n Submit Invalid Credentials ==> Error Page\n\nWelcome Page\n Title Should Be Welcome Page\n [Actions]\n Go to ${LOGIN_PAGE_URL} ==> Login Page\n\nError Page\n Title Should Be Error Page\n [Actions]\n Go to ${LOGIN_PAGE_URL} ==> Login Page\n\n*** Keywords ***\nSubmit Valid Credentials\n Submit Credentials ${VALID_USERNAME} ${VALID_PASSWORD}\n\nSubmit Invalid Credentials\n Submit Credentials invalid_username invalid_password\n\nSubmit Credentials\n [Arguments] ${username} ${password}\n Input Text ${USERNAME_FIELD} ${USERNAME}\n Input Password ${PASSWORD_FIELD} ${PASSWORD}\n Click Button ${LOGIN_BUTTON}\n```\n\nNOTE! This machine can generate infinite number of test sequences thus you need to constraint the generation.\nFor example:\n\n robomachine --tests-max 10 --actions-max 20 --to-state 'Welcome Page' --generation-algorithm random [MACHINE_FILE_NAME]\n\nwill generate 10 random tests with at most 20 actions each and all tests ending to state 'Welcome Page'.\n\n## Installation\n\nFrom [Python Package Index](http://pypi.python.org/pypi)\n\n pip install RoboMachine\n\n\nFrom source:\n\n git clone git://github.com/mkorpela/RoboMachine.git\n cd RoboMachine\n python setup.py install\n\nAfter this you should have a commandline tool called `robomachine` available.\nSee `robomachine --help` for commandline tool usage.\n\n## Syntax\n\n* Only supported Robot Framework format is space separated format.\n* You should use `.robomachine` suffix for your Machine files.\n* You can have a Robot Framework *Settings* table at the beginning of the machine file.\n* You can have a Robot Framework *Variables* table after the optional Settings table.\n* *Machine* table is a must.\n* You can have a Robot Framework *Keywords* table after the Machine table.\n\n## Machine table syntax\n\nUsed machine variables must be introduced at the beginning of the machine table. Valid machine variable is a valid Robot Framework variable that contains only uppercase characters A-Z, numbers (not at the start) 0-9 and\nunderscores (`_`). For example: `${VALID_123}` is a valid machine variable.\n\nAn example of a valid machine variable definition line::\n\n ${VALID_VARIABLE_1} any of Value 1 Value 2 Value 3\n\nRules about the machine variables should be next. Rule building blocks:\n* Variable conditions:\n * `${VARIABLE} == value`\n * `${VARIABLE} != value`\n * `${VARIABLE} < value`\n * `${VARIABLE} <= value`\n * `${VARIABLE} > value`\n * `${VARIABLE} >= value`\n * `${VARIABLE} in (a, b)` # short for ${VARIABLE} == a or ${VARIABLE} == b\n * `${VARIABLE} ~ REGEX` # python regexp: re.search(REGEX, ${VARIABLE}) != None\n * `${VARIABLE} !~ REGEX` # negated regexp match\n* And rule: [some condition] and [some other condition]\n* Or rule: [some condition] or [some other condition]\n* Not rule: not ([some condition])\n* Implication rule: [some condition] ==> [some condition]\n* Equivalence rule: [some condition] <==> [some condition]\n* [some condition]: Variable condition OR (rule)\n\nRules can be used to remove variable combinations that should not be used in\ntest generation.\n\nAn example of a valid rule line:\n\n ${VARIABLE_1} == Value 1 ==> (${FOO} == bar or ${FOO} == zoo)\n\nWhich means: When `${VARIABLE_1}` value is \"Value 1\" then `${FOO}` should either be \"bar\" or \"zoo\".\n\nState blocks should be next. First state block is the starting state.\n\nState block starts with a line containing the states name. Valid state name contains only upper and lowercase characters a-zA-Z, numbers (not at the start) 0-9 and spaces (not at the start or end and only one\nbetween words).\n\nThis is followed by the Robot Framework steps that should be executed when in that\nstate.\n\nThis can be followed by an actions block definition.\n\nAn actions block starts with `[Actions]` tag and is followed by one or more action lines.\n\nAn action line has four parts:\n* A Robot Framework step that is executed when the action happens (action label) (you can also leave this out - use a tau transition)\n* ` ==> ` right arrow with two spaces before and after\n* Name of the state that the machine ends up when the action is taken (end state)\n* Optional rule (when the action is available) this either starts with\n ` when ` and the rule or ` otherwise ` - meaning this action should be taken when\n all of the other actions with same action label are not available\n\nAn example of a valid state definition::\n\n```robotframework\nState Name\n Robot Framework Step with ${arguments}\n Log something WARN\n [Actions]\n Log other thing ==> Other State when ${FOO} == bar\n Log other thing ==> Another State when (${FOO} == zoo and ${BAR} == goo)\n Log other thing ==> End State otherwise\n Log nothing ==> End State\n ==> Some state # This here is a tau transition that does not write a step to the test\n```\n",
"bugtrack_url": null,
"license": "Apache License, Version 2.0",
"summary": "Test data generator for Robot Framework",
"version": "0.10.0",
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"md5": "4da07d05fdc32a307d3724b73e4d3ee2",
"sha256": "5ebc47695f54ee66764efc921c69baab0d40b28ba4a69cf03eae30b9f2232fe9"
},
"downloads": -1,
"filename": "RoboMachine-0.10.0.tar.gz",
"has_sig": false,
"md5_digest": "4da07d05fdc32a307d3724b73e4d3ee2",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 12601,
"upload_time": "2022-12-30T15:09:28",
"upload_time_iso_8601": "2022-12-30T15:09:28.218266Z",
"url": "https://files.pythonhosted.org/packages/c6/cd/d3de0a099abeb4ca51497ef9a4c4d875ea0c401b2915fc3f6ec031fadefd/RoboMachine-0.10.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2022-12-30 15:09:28",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "mkorpela",
"github_project": "RoboMachine",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "argparse",
"specs": [
[
"~=",
"1.4.0"
]
]
},
{
"name": "pyparsing",
"specs": [
[
"~=",
"2.4.7"
]
]
},
{
"name": "allpairspy",
"specs": [
[
"~=",
"2.5.0"
]
]
},
{
"name": "pip",
"specs": [
[
"~=",
"22.2.2"
]
]
},
{
"name": "wheel",
"specs": [
[
"~=",
"0.37.1"
]
]
},
{
"name": "setuptools",
"specs": [
[
"~=",
"65.3.0"
]
]
},
{
"name": "robotframework",
"specs": [
[
"~=",
"6.0.1"
]
]
}
],
"lcname": "robomachine"
}