Test Automation With Python
Loadero
Posted on July 28, 2022
According to IEEE Spectrum Python is the top programming language of 2021, and since April Loadero supports Python as a test script language. Many engineers agree that test automation with Python is an excellent choice, and in this blog post, we’ll show the basics of it.
Python tests in Loadero use the Py-TestUI framework. Py-TestUI wraps and implements additional features for Selenium Python binding. This means that Loadero Python tests can utilize the full power of Selenium and other cool features provided by Py-TestUI.
Test Structure
Every Python test starts with
def test_on_loadero(driver: TestUIDriver) -> None:
This function is like the main
function in other programming languages. It will be called once the test execution is started. All of the test logic must originate from this function. This means that additional functions outside of the test_on_loadero
function can be added, but they must be called from the test_on_loadero
function to have any effect.
Driver
Loadero tests automate browser interactions as if they were done by a human to allow for repeated execution, parallel tests, and scale-up for load testing. Tests can do almost any action that a human can in a browser, for example:
- Navigate to URL
- Click on links and elements
- Input text
- Copy text
These actions are achieved in a test with the driver
object. driver
wraps the workhorse of the browser test – Selenium WebDriver and is of type TestUIDriver. TestUIDriver
implements commonly used browser interactions to improve ease of use but at the same time allows to access the underlying Selenium WebDriver for more complex browser interactions.
driver
object is initialized and configured at the start of every test and passed as an argument to the test_on_loadero
function.
Let’s look at common browser interactions and how to implement them in a test script.
Navigation
To start interacting with a web page, it first has to be opened. To do that call the following method
TestUIDriver.navigate_to(url: str) -> None
Argument url
is the URL of a web page to open.
Here is a simple test that demonstrates the usage of navigate_to
.
def test_on_loadero(driver: TestUIDriver) -> None:
driver.navigate_to("https://duckduckgo.com/")
driver.save_screenshot("duckduckgo.png")
Additionally, the test calls
TestUIDriver.save_screenshot(image_name: str) -> str
This method will, as the name implies, capture the state of the browser at the moment of the save_screenshot
method call and save it with the name supplied by image_name
argument. After the test finishes execution, all screenshots taken during the test will be available in the artifacts tab in the Loadero result page of a single test participant.
Tip: Taking screenshots during a test is a common practice that helps test debugging or manually reviewing what was on the test participant’s screen at the important stages of your test.
Clicks
A very fundamental browser interaction is the click. To interact with an element it first has to be located with the e
method.
TestUIDriver.e(locator_type: str, locator: str) -> Elements:
locator_type
argument describes the location method of an element and can have values:
-
css
– locate element by CSS selector -
name
– locate element by name -
className
– locate the element by its class name -
xpath
– locate element by XPath
locator
– describes how to locate the element with the location method set by locator_type
argument. To learn more about using CSS selectors and XPath locators in your Selenium test automation scripts make sure to read this blog post.
An attentive reader might have noticed that e
method has return type Elements
– plural, but I have been using elements in a singular form so far. This is because Elements
object has more advanced features (for example – locating multiple elements at once, image matching) that this blog post does not cover. So in an attempt not to confuse the reader these topics will be skipped.
After locating the desired element it can be clicked on with the click
method.
Elements.click() -> Elements:
There is nothing in the way for calling click
right after an element has been located, but a good practice is to check if the element is visible with a runtime assertion before clicking on it. If the element is visible then it has had enough time to load and can be interacted with. Doing this allows avoiding test failures caused by attempting to click on an element that has not loaded yet. We use a lot in tests we create for our customers and advise you to do the same.
wait_until_visible
method does as the name suggests – waits for the element to load and become visible before attempting further interactions.
Elements.wait_until_visible(seconds=10.0, log=True) -> Elements:
Argument seconds
with a default value of 10.0 specifies the amount of time the test will wait until the element becomes visible. If the element is not visible after waiting the specified time an error will be raised and the test will fail.
Argument log
with a default value True specifies whether to log the result of the wait_until_visible
method call. This argument generally should not be changed and can be ignored. Many Elements
methods have a log
argument and it can be ignored in all of them.
Here is a simple test script showcasing everything shown so far. You can put everything learned so far to test with Loadero’s free trial. You can also find the script example in Loadero’s Github repository.
def test_on_loadero(driver: TestUIDriver) -> None:
# Opens the search engine DuckDuckGo with default search query of
# google.com
driver.navigate_to("https://duckduckgo.com/?q=google.com")
# Locates an element with a CSS selector that is pointing to the first
# search results title, waits for the element to become visible and clicks
# on it.
driver.e("css", "#r1-0 > div > h2").wait_until_visible().click()
# Ensures that the web page has loaded before taking a screenshot.
driver.e("css", "body > div:first-of-type").wait_until_visible()
driver.save_screenshot("google.png")
Input Text
The previous test script example was cheating a bit. Realistically a human user would insert the search query “google.com” themselves and wouldn’t be using a specially prepared URL. To simulate this behavior, tests can input text with the .send_keys
method.
Elements.send_keys(value: str, log=True) -> Elements:
value
argument specifies the text that will be sent to an element.
To clear the input value that was set by send_keys
or an element has by default use clear
method.
Elements.clear() -> None:
Retrieving Content of an element
Browser interactions can be generalized as a feedback loop where the next interaction is determined by the resulting content of a web page. Tests need a way to retrieve the content of a web page or more specifically the content of a single element to implement logic that decides what the next interaction should be. This section will cover the other half of the browser interaction feedback loop – content retrieval.
Most HTML elements have content, with few exceptions like <br>
element, that is rendered to the web page and can be interacted with.
To retrieve the textual value of an element use
Elements.get_text() -> str:
Putting Everything Learned To Use
It’s time to combine all the commands we have described in a single test automation script. This script example performs a search for a specific query on the DuckDuckGo search engine and prints out the top results.
def test_on_loadero(driver: TestUIDriver) -> None:
# The main logic of the test is in top_search_results function
print(top_search_results(driver, "loadero", 10))
# top_search_results returns the top n search results for search_query.
def top_search_results(driver: TestUIDriver, search_query: str, n: int) -> str:
# Limits the search result count to 10, because a single search query in
# DuckDuckGo search engine returns only 10 results.
n = min(n, 10)
# Selectors.
home_page_search_bar = "#search_form_input_homepage"
home_page_search_button = "#search_button_homepage"
# Opens the search engine DuckDuckGo.
driver.navigate_to("https://duckduckgo.com/")
# Locates search bar, waits for the element to load and sends a search query
# to it
driver.e("css", home_page_search_bar).wait_until_visible().send_keys(
search_query
)
# Locates search button, verifies that it is visible and clicks it.
driver.e("css", home_page_search_button).wait_until_visible().click()
result = f"Top {n} DuckDuckGo search results for {search_query} ->\n"
# Iterates over top n search results
for i in range(n):
# Creates a CSS selector that indicates to the search result title.
selector = f"#r1-{i} > div > h2 > a.result__a"
# Locates the search element and verifies that it is visible.
search_result_element = driver.e("css", selector).wait_until_visible()
# Retrives the title of search result and adds it to result string.
title = search_result_element.get_text()
result += f"\t {title} \n"
return result
You can find the output of this test script in Loadero’s single participants result pages logs tab under Selenium log. The output would log something like this:
Top 10 DuckDuckGo search results for loadero ->
Loadero - Performance and Load Testing Tool
Loadero | LinkedIn
Loadero Pricing, Alternatives & More 2022 - Capterra
Loadero - Home | Facebook
GitHub - loadero/examples: Test script examples that are ...
Loadero - YouTube
Loadero - your performance & load testing partner from the ...
Application Load Testing Tools for API Endpoints with ...
Tractors - Tractor Loader Backhoe - B26 | Kubota
EZ Loader TMS | EZ Loader TMS
We covered the basics of working on test automation with Python. You can create a test similar to what we described and run it multiple times free of charge with Loadero’s free trial. To continue learning to use Python for your tests in Loadero make sure to visit our Wiki, where you can find information about custom commands that extend the functionality WebDriver and PyTestUI, variables that hold the relevant information about the test participant, and more script examples of test automation with Python. We will be glad to see you back again.
Posted on July 28, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
August 29, 2024