{"id":15018760,"url":"https://github.com/eldaduzman/robotframework-gevent","last_synced_at":"2025-10-23T22:30:39.757Z","repository":{"id":58858277,"uuid":"532345359","full_name":"eldaduzman/robotframework-gevent","owner":"eldaduzman","description":"Run robotframework keywords asynchronously with the power of gevent","archived":false,"fork":false,"pushed_at":"2024-04-26T00:44:45.000Z","size":916,"stargazers_count":12,"open_issues_count":15,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-09-26T20:52:08.639Z","etag":null,"topics":["asynchronous-programming","atdd","automation","python","robotframework","rpa","test-automation"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eldaduzman.png","metadata":{"files":{"readme":"README.md","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}},"created_at":"2022-09-03T18:41:26.000Z","updated_at":"2024-04-25T22:05:09.000Z","dependencies_parsed_at":"2023-02-12T23:01:43.541Z","dependency_job_id":null,"html_url":"https://github.com/eldaduzman/robotframework-gevent","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eldaduzman%2Frobotframework-gevent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eldaduzman%2Frobotframework-gevent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eldaduzman%2Frobotframework-gevent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eldaduzman%2Frobotframework-gevent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eldaduzman","download_url":"https://codeload.github.com/eldaduzman/robotframework-gevent/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219867717,"owners_count":16555814,"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":["asynchronous-programming","atdd","automation","python","robotframework","rpa","test-automation"],"created_at":"2024-09-24T19:52:25.266Z","updated_at":"2025-10-23T22:30:39.371Z","avatar_url":"https://github.com/eldaduzman.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# robotframework-gevent\n\u003c!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --\u003e\n[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-)\n\u003c!-- ALL-CONTRIBUTORS-BADGE:END --\u003e\nRun keywords asynchronously with the power of gevent\n\n\n[![Version](https://img.shields.io/pypi/v/robotframework-gevent.svg)](https://pypi.python.org/pypi/robotframework-gevent)\n![](https://raw.githubusercontent.com/eldaduzman/robotframework-gevent/main/docs/badges/coverage-badge.svg)\n![](https://raw.githubusercontent.com/eldaduzman/robotframework-gevent/main/docs/badges/pylint.svg)\n![](https://raw.githubusercontent.com/eldaduzman/robotframework-gevent/main/docs/badges/mutscore.svg)\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n\n## installation:\n```bash\npip install robotframework-gevent\n```\n\n## Usage:\n\n```robotframework\n# simple-test.robot\n*** Settings ***\n\nLibrary             Collections\nLibrary             String\nLibrary             GeventLibrary\nLibrary             RequestsLibrary\n\n\n*** Test Cases ***\nTest1\n    [Documentation]    Simple test flow with gevent greenlets\n    Log    Hello World\n    Create Gevent Bundle    alias=alias1  # Create a bundle of coroutines\n    Sleep    10s    alias=alias1    # run your synchronous keyword\n    # register all your keywords as coroutines to the gevent bundle\n    Add Coroutine    Sleep Wrapper    alias=alias1\n    Add Coroutine    Sleep    20s    alias=alias1\n    Add Coroutine    Sleep    10s    alias=alias1\n    Add Coroutine    GET    https://jsonplaceholder.typicode.com/posts/1    alias=alias1\n    Add Coroutine    Convert To Lower Case    UPPER\n\n    # Run your coroutines and get the values by order\n    ${values}    Run Coroutines    alias=alias1\n    Log Many    @{values}\n\n    # The 3rd coroutine was a request, take it's value\n    ${jsonplaceholder_resp}    Get From List    ${values}    3\n\n    # assert the returned response code to be 200\n    Status Should Be    200    ${jsonplaceholder_resp}\n    # assert that the returned `userId` field equals to 1\n    Should Be Equal As Strings    1    ${jsonplaceholder_resp.json()['userId']}\n\n\n*** Keywords ***\nSleep Wrapper\n    Sleep    1s\n\n```\n\n\nSee -  [Keyword Documentation](https://eldaduzman.github.io/robotframework-gevent/GeventLibrary.html)\n### run test:\n```\n\u003e\u003e\u003e robot simple-test.robot\n```\n### Possible result\n\nAfter test is completed go to `log.html`:\n\n![](https://raw.githubusercontent.com/eldaduzman/robotframework-gevent/main/docs/images/Possible-Log-File.png)\n\n\nOwing to the fact that keywords are executed asynchronously, we cannot know the order of keyword execution, so instead they are printed in a table format\n\n\n### For more examples\n\ngo to [examples](https://github.com/eldaduzman/robotframework-gevent/tree/main/examples)\n## Motivation\n\nModern software architecture is `event driven`, with many background process.\nServers are being more pro-active instead of re-active as we see in a `client server` architecture.\n\nIn order to test such systems, we need the ability to run coroutines in our test scripts.\n\nWith the power of [gevent](http://www.gevent.org/), we can run several coroutines in greenlets, so integrating them into our robotframework test script will provide super powers to our testing efforts!\n\n## Why gevent?\n\nConcurrency can be achieved in 3 different ways:\n\n1.  Multiprocessing - running each task in it's own `process`.\n    The cons of such an approach would be massive consumption of resources, namely CPU and memory, as this means to allocate an entire `memory heap` to each task.\n    Another problem is a possible need for `Inter-Process Communication (IPC)` that might be costly.\n\n2.  Multithreading - running each task in a `thread`.\n    Unlike multiprocessing, now all tasks run on the same memory heap and separated by threads, which the CPU coordinates using `round-robin`.\n    However, python's  `Global Interpreter Lock` (GIL) prevents these threads from acting concurrently, it might perform context switching when IO operation occurs but there's no control for that.\n\n\n3.  Asynchronous IO - running all tasks on a single thread, while IO operations won't block the progress of the program, while code execution is committed by an   `event loop` that `selects` between attached `coroutines`.\n    This is highly efficient in resources consumption when compared to multithreading and multiprocessing, but it requires some modifications to the original code.\n    `Blocking` IO statements can hog the event loop and the code will not be concurrent.\n    `gevent` allows programmers to write seemingly regular \"blocking\" python code, but it will enforce asynchronous IO compliance by `monkey patching`\n\n## File structure\n```\n\n|   LICENSE\n|   .gitignore\n|   .pylintrc\n|   pyproject.toml\n|   poetry.lock\n|   README.md\n\n|           \n+---src\n|   \\---GeventLibrary\n|       |   \\---exceptions\n|       |       |   __init__.py\n|       |   \\---keywords\n|       |       |   __init__.py\n|       |       |   gevent_keywords.py\n|       |   __init__.py\n|       |   gevent_library.py\n|               \n+---atests\n|   |   __init__.robot\n|   |   simple-test.robot\n|   |   \n|   \\---utests\n|       |   __init__.py\n|       |   test_bundle_creation.py\n\n```\n## Code styling\n### `black` used for auto-formatting code [read](https://pypi.org/project/black/),\n### `pylint` used for code linting and pep8 compliance [read](https://pypi.org/project/pylint/),\n### `mypy` used for type hinting [read](https://pypi.org/project/mypy/),\n### `robocop` static code analyzer for robotframework [read](https://pypi.org/project/robotframework-robocop/),\n### `perflint` pylint extension for performance linting [read](https://betterprogramming.pub/use-perflint-a-performance-linter-for-python-eae8e54f1e99)\n### `cosmic-ray` Python tool for mutation testing [read](https://python.plainenglish.io/python-mutation-testing-with-cosmic-ray-4b78eb9e0676)\n\n## links\n1. [Robotframework](https://robotframework.org/)\n2. [gevent](http://www.gevent.org/)\n## Contributors ✨\n\nThanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/MalikMlitat\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/19836100?v=4?s=100\" width=\"100px;\" alt=\"MalikMlitat\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMalikMlitat\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/eldaduzman/robotframework-gevent/commits?author=MalikMlitat\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feldaduzman%2Frobotframework-gevent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feldaduzman%2Frobotframework-gevent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feldaduzman%2Frobotframework-gevent/lists"}