UI Testing with PyTest and Selenium

Automated testing allows you execution of script, that doesn’t require human interactions. This document helps you create and execute automated testing.

This document assumes that we’re testing Web Application, anything that runs in Browser can be automatically tested.

Approach to Automated Testing

  1. Perform actions: Click, Keying in Data etc.
  2. Perform assertions: assert
  3. Move to next test

Pre-requisite

  1. Make a list of test cases
  2. Write a description of every test case
  3. Write down the expected and actual results of the test case
  4. Test manually first, to ensure consistency

Recording Tests

Selenium is a tool that allows us test automatically via Browser. We will be using specifically Katalon, this allows us to record and export code.

Installing Katalon Recorder

  1. Open Chrome/Firefox browser
  2. Click on the kebab menu on the top right side of the URL bar
  3. Click on more tools/Add-ons , select extensions option
  4. After getting redirected to the extension page search for katalon/selenium recorder.
  5. Then click on add extension, it will get added to the browser

Recording Actions

  1. Open recorder from the extension list
  2. After opening the recorder, click on new+ button on the navbar
  3. Click on + sign on the sidebar of the recorder after a window pop-ups.Provide the test suite name and click on ok/submit button
  4. After clicking on the New button we can provide the name of the test case. Things to remember while naming test: Make it relevant. Click on the OK button, once done
  5. Now click on the Record button present on the navbar, this will redirect to the chrome browser
  6. Now start testing/recording the test case, perform all actions as you’d normally do
  7. Now switch back to the recorder app or page and click on the STOP button
  8. Click on the PLAY button beside the record button, and click on the timer icon on the top right side of the page, by using the timer option the user can control the speed of the running test case

Exporting Test cases

  1. Click on the Export button on the navbar
  2. An export window will pop up
  3. Select the desired scripting format python/pytest
  4. Click on Save as a file or copy to clipboard paste it on some other location

PyTest integration

According to Official Website

The pytest framework makes it easy to write small tests, yet scales to support complex functional testing for applications and libraries.

By convention pytest will look for anything with test_ extension as prefix, including all the sub-directories.

Installation

  1. Run pip install pytest on terminal
  2. Check that you installed the correct version(pytest –version)

pytest allows you to configure different aspects using conftest.py. Typically setup and teardown functions are supported using fixtures.

According to official documentation

pytest fixtures offer dramatic improvements over the classic xUnit style of setup/teardown functions:

  • fixtures have explicit names and are activated by declaring their use from test functions, modules, classes or whole projects.
  • fixtures are implemented in a modular manner, as each fixture name triggers a fixture function which can itself use other fixtures.
  • fixture management scales from simple unit to complex functional testing, allowing to parametrize fixtures and tests according to configuration and component options, or to re-use fixtures across function, class, module or whole test session scopes.

Following is sample setup of fixture in conftest.py

@pytest.fixture(scope='session')
def setup(request):
    chromedriver = "/usr/local/bin/chromedriver"
    print("\Initiating chrome driver")
    driver = webdriver.Chrome(chromedriver, chrome_options=options)
    session = request.node
    for item in session.items:
        cls = item.getparent(pytest.Class)
        setattr(cls.obj, "driver", driver)
    driver.implicitly_wait(30)
    yield driver
    time.sleep(2)
    driver.close()

Here, as users can see we have used a mark fixture for a set up function which contains the browser/driver path, chromedriver, chrome_options=options are options that you can use to customize and configure a ChromeDriver session.

Locators

Locators allow us to search for element on which to perform operations on. Remember HTML is a tree, finding right element to operate on is important. Some actions that can be performed include:

  1. Click on Element {E.g. Button, Links etc}
  2. Input on Element {E.g. Updating Username and Password}

To locate element on Web Page there are few methods:

  1. Using ID: driver.find_element_by_id(“email”).click()
  2. Using Class Name: driver.find_element_by_class_name(“Container”).click()
  3. Using Name Attribute: driver.find_element_by_name(“password”).send_keys(“test”)
  4. Using XPATH: driver.find_element_by_xpath(//button[text()=’Ok’]).click()
  5. Using Link Text: driver.find_element_by_link_text(“Sign Out”).click()
  6. Using CSS Selector: driver.find_element_by_css_selector(‘p.content’)

Interacting with Page

Selenium’s Docs on Navigating shows few examples

  1. Sending Keys: element.send_keys(“some text”) or element.send_keys(” and some”, Keys.ARROW_DOWN)
  2. Clearing Element: element.clear()
  3. Clicking: driver.find_element_by_id(“submit”).click()

Tips for Debugging

  1. Run every test case at least twice
  2. Also run entire test suite and check behaviour of Web Application
  3. Solve runtime error as soon as possible
  4. Make sure your assert statements are corrects
  5. Code Review your tests
  6. Use DRY method in the tests