Python libraries for Robot Framework
Introduction
This article is a continuation of the article
«Robot Framework Test Architecture»
From it you can learn how to connect your
Python
libraries to Robot Framework tests.
It is assumed that in addition to the article on
architecture
you have mastered
installation
and
the basics of
Robot Framework.
You can read about several ways to specify the path to libraries and resources
here
.
Connect your Python library
Robot Framework allows you to do a lot of complex tests without going beyond the .robot files.
However, I am one of those robot users who prefer to shift the main load
to Python libraries, and keep .robot files as simple as possible.
Libraries are usually stored in the lib, libraries, Lib, Libraries, and similar directories. Import can be done
by specifying a relative path.
In my experience in
Linux
systems, .py after the library can be omitted. I will do this first for clarity and
compatibility.
*** Settings *** Library ../libraries/app.py
If the library has a function some_name(), then it should be called from the robot without brackets, replacing the underscore with a space and making the first letters of words capital - that is, like Some Name
Simple example
Let's consider the test demo.robot which receives a random number from a range from an external library.
random_demo/ |-- Libraries | `-- custom_random.py `-- Tests `-- demo.robot
# custom_random.py from random import randrange def get_random_number(limit) -> int: return randrange(int(limit))
*** Settings *** Documentation Example that uses external python library Library ../Libraries/custom_random.py *** Test Cases *** Check Smallest Limit ${number}= Get Random Number 1 Should Be Equal As Integers ${number} 0
Note how the
function
get_random_number() is called as the keyword Get Random Number
Argument
1 is passed without brackets after four spaces.
python -m robot .\demo.robot
============================================================================== Demo :: Example that uses external python library ============================================================================== Check limit | PASS | ------------------------------------------------------------------------------ Demo :: Example that uses external python library | PASS | 1 test, 1 passed, 0 failed ============================================================================== Output: C:\Users\Andrei\robot\random_demo\Tests\output.xml Log: C:\Users\Andrei\robot\random_demo\Tests\log.html Report: C:\Users\Andrei\robot\random_demo\Tests\report.html
Example with UI
Let's look at an example of the UI of the test: the Python library gives one URL after another.
Robot goes to this address and checks whether the header matches the expected value.
In the part of
the test runs
there will be
PASS, in the part of
FAIL
Make sure that you have
installed and configured
the library
robotframework-browser
ext_py_lib/ |-- browser |-- libraries | `-- unstable_url.py `-- tests `-- test_title.robot
from random import randrange def get_unstable_url() -> str: if randrange(2) == 1: return "https://www.urn.su" else: return "https://www.heihei.ru"
*** Settings *** Documentation Example that opens single page Library Browser ... enable_playwright_debug=${True} ... auto_closing_level=TEST ... retry_assertions_for=0:00:03 Library ../libraries/unstable_url.py Force Tags ui *** Variables *** *** Keywords *** Test Setup Tasks Start Chromium Browser Test Teardown Tasks Close Browser Start Chromium Browser New Browser browser=chromium headless=True New Context viewport={'width': 1920, 'height': 1080} ignoreHTTPSErrors=True *** Test Cases *** Starting a browser with a page [Tags] title ${url} = Get Unstable Url New Page ${url} Get Title == URN.SU Close Browser
robot tests
============================================================================== Tests ============================================================================== Tests.Test Title :: Example that opens single page ============================================================================== Starting a browser with a page | PASS | ------------------------------------------------------------------------------ Tests.Test Title :: Example that opens single page | PASS | 1 test, 1 passed, 0 failed ============================================================================== Tests | PASS | 1 test, 1 passed, 0 failed ============================================================================== Output: C:\Users\Andrei\robot\ext_py_lib\output.xml Log: C:\Users\Andrei\robot\ext_py_lib\log.html Report: C:\Users\Andrei\robot\ext_py_lib\report.html
robot tests
============================================================================== Tests ============================================================================== Tests.Test Title :: Example that opens single page ============================================================================== Starting a browser with a page | FAIL | Title 'HeiHei.ru' (str) should be 'URN.SU' (str) ------------------------------------------------------------------------------ Tests.Test Title :: Example that opens single page | FAIL | 1 test, 0 passed, 1 failed ============================================================================== Tests | FAIL | 1 test, 0 passed, 1 failed ============================================================================== Output: C:\Users\Andrei\robot\ext_py_lib\output.xml Log: C:\Users\Andrei\robot\ext_py_lib\log.html Report: C:\Users\Andrei\robot\ext_py_lib\report.html
For information on how to add the ability for Python functions to write to the robot log and/or console, read here
More complex example
Example of testing a Desktop application using the library PyWinAuto you can study here
Example with OOP
Based on the first example from this article, we will consider connecting a library with OOP.
Previously, the keyword was a regular
function
get_unstable_url().
Now the library will have
class
CustomRandom
with
method
get_unstalbe_url()
Rename
custom_random.py
to
CustomRandom.py
- so that the file name matches the class name.
So the robot will be able to understand that we are importing as a library.
keyword_demo/ |-- Libraries | `-- CustomRandom.py `-- Tests `-- demo.robot
# CustomRandom.py from random import randrange class CustomRandom: def get_random_number(self, limit) -> int: return randrange(int(limit))
File demo.robot remains unchanged
*** Settings *** Documentation Example that uses external python library Library ../Libraries/CustomRandom.py *** Test Cases *** Check Smallest Limit ${number}= Get Random Number 1 Should Be Equal As Integers ${number} 0
python -m robot .\keyword_demo\Tests\demo.robot
============================================================================== Demo :: Example that uses external python library ============================================================================== Check Smallest Limit | PASS | ------------------------------------------------------------------------------ Demo :: Example that uses external python library | PASS | 1 test, 1 passed, 0 failed ==============================================================================
@keyword
By default, the keyword name is derived from the function or method name by replacing _ with a space and capitalizing the first letters of all words.
So the function
my_keyword()
will match the keyword
My Keyword
Using the
decorator
keyword from robot.api.deco, you can make the keyword name independent of the method name.
Let's leave the method name get_random_number() but specify the name
Super Random in @keyword
# CustomRandom.py from random import randrange from robot.api.deco import keyword class CustomRandom: @keyword(name="Super Random") def get_random_number(self, limit) -> int: return randrange(int(limit))
In demo.robot you now need to use Super Random, it will no longer be able to find the old name Get Random Number.
*** Settings *** Documentation Example that uses external python library Library ../Libraries/CustomRandom.py *** Test Cases *** Check Smallest Limit ${number}= Super Random 1 Should Be Equal As Integers ${number} 0
python -m robot .\keyword_demo\Tests\demo.robot
============================================================================== Demo :: Example that uses external python library ============================================================================== Check Smallest Limit | PASS | ------------------------------------------------------------------------------ Demo :: Example that uses external python library | PASS | 1 test, 1 passed, 0 failed ==============================================================================
If you add the keyword_demo directory to your PYTHONPATH, you can import the CustomRandom library as follows.
Library Libraries.CustomRandom
For clarity, we will add using
--pythonpath
You can study the full code in the article
Robot Framework Basics: System Path
python -m robot --pythonpath .\keyword_demo .\keyword_demo\Tests\demo.robot
Keywords in Russian
From the
previous chapter
it is clear that with @keyword you can change the names of keywords.
You can use names in Russian as new names.
# CustomRandom.py from random import randrange from robot.api.deco import keyword class CustomRandom: @keyword(name="Сгенерировать случайное число") def get_random_number(self, limit) -> int: return randrange(int(limit))
*** Settings *** Documentation Example that uses external python library Library ../Libraries/CustomRandom.py *** Test Cases *** Проверить Наименьший Лимит ${number}= Сгенерировать случайное число 1 Should Be Equal As Integers ${number} 0
python -m robot .\keyword_demo\Tests\demo.robot
============================================================================== Demo :: Example that uses external python library ============================================================================== Проверить Наименьший Лимит | PASS | ------------------------------------------------------------------------------ Demo :: Example that uses external python library | PASS | 1 test, 1 passed, 0 failed ==============================================================================
There was a pretty funny bug with @keyword. When @keyword was used in a library, like this
from robot.api.deco import keyword @keyword def example(): pass
Not only the Example keyword was created, but also the keyword Keyword
| Robot Framework | |
| Architecture | |
| Logs | |
| __init__.robot | |
| Create custom .py libs | |
| Path to libs and resources | |
| Keyword as decorator | |
| Template | |
| Parametrize | |
| Demo with pywinauto |