Selenium For Testing SegAnnDB

Selenium

Selenium is a browser based testing framework which is very widely used for doing testing for various web centric apps. Selenium has bindings available for almost all the languages. Selenium is used exclusively for automating browser behaviour. In more simpler words, selenium can be described as an API for the browser. Selenium is also used in web scraping.

For python, selenium can be installed by one single command - pip install selenium

Browser based testing

Browser based testing is automating browsers for running regression and functional tests, which further test the functionality of the web application. The aim is to reduce the number of regressions which might be introduced in further development of the application.

Python unit testing

Python unittest is a module which is used for writing tests in python. It provides various methods for running and setting up of tests.

  • Each test case method should be prefixed with the name “test_”
  • For defining the test sequence of methods, the format is - “test010_” , “test020_” etc.
  • There should be a setUp method in the file. This method is called before running up of each test case.
  • Method tearDown is called every time a test case method finishes executing.

Directory Structure

All the data related to the tests goes under SegAnnDB/tests/ directory.

Test Profile

For doing the testing I am using a profile named ES0004. The script automatically checks for the existence of the test profile. In case, it does not exist it downloads it from my github repo and then the test suite execution begins. It expects that the test profile is inside SegAnnDB/tests/

Test Profile

The Test Cases -

After some initial discussions, me and Toby (my mentor) decided that it would be good if I wrote test cases for checking the current functionality of application. The test cases are -

  1. Test whether the application is starting properly or not

    Implementing this test case was trivial. We are just checking for the right value in the page title after succssfully loading the page.

  2. Login the user

    By far this was the trickiest part. The normal login flow in SegAnnDB is as follows -

    a) Click on the signin button
    b) A new pop up opens up for mozilla persona
    c) Enter the mail id
    d) The pop is redirected to appropriate oauth based server of your email provider for asking permissions.
    e) Enter your password andd authorize
    f) Redirects back to mozilla persona
    g) Pop up closes and the user is successfully logged in

    Automating this many steps and handling so many steps was complicated. I was sure that other people must have tried to automate mozilla persona based logins. I came across mockmyid which is very useful for testing mozilla persona based applications for mock users.

    mockmyid provides mock user ids which can be used for logging in via mozilla persona. When using mockmyid the login flow is as follows -

    a) Click on signin button
    b) Persona popup opens
    c) Enter mockmyid based email
    d) Click on login
    e) Pop closes and the user is logged in.

    Assertion for a successfull login works by checking for the presence of Sign Out field.

    Login is something which is used by every other test case, so I decided to make a method which can automatically log the user in.

    The login function

  3. Upload a profile

    Uploading a profile is also straightforward. The steps followed by webdriver are -

    a) Login the user
    b) Go to profile upload page
    c) Put in the path of test file
    d) Click on submit button
    e) Assert for existence of element with id=success

  4. Annotate a chromosome

    This test case works very differently when compared to other test cases. It uses selenium only for logging in the user. The annotation part is done by using urllib2 module and sending out the get requests to the web server. The assertion works by checking for the 200 status code on the response of the request sent.

    But there is one more thing with this test. It needs to sleep for a while. This is because, it will get called directly after the profile is uploaded. Now, SegAnn needs some time to process a profile before it can be annotated. So the test for annotating chromosome waits for about a minute before doing anything.

  5. Delete a profile.

    Deleting of a profile is simple as well. The steps followed are -

    a) Login the user
    b) Send a delete request to the server
    c) Assert for word “deleted” on the source code of the response.

    Now, as we will go on adding more features into SegAnn I plan to add tests for each of them.

All the code related to above tests can be found at github.

Waits in Selenium

Generally selenium is kindof procedural and does not handle latency very well. But with webapps, its sure that there will be some delays and waits while the page loads.

To handle these kinds of scenarios we need to put in waits in selenium while checking for existence of various elements. So, basicallly what I’m doing is I poll the browser continuously for a max time limit, and check whether a certain element exists or not

There are two major types of waits available in selenium-

  • Implicit Waits - An implicit wait is to tell web driver to poll the DOM for a certain amount of time when trying to find and element or elements if they are not immediately available.

    Example code -

    from selenium import web driver
    driver = webdriver.Firefox()
    driver.implicitly_wait(30)
    driver.get("https://www.google.co.in/")
    driver.find_element_by_id(“lst-ib”)
    

    In above example the implicit wait value is given as 30sec i.e., if web driver is able to find the element with in the given span 30sec, it returns true else, it will raise an exception.

  • Explicit Waits- An explicit wait is code we define to wait for a certain condition to occur before proceeding further in the code. time.sleep() is one such example.

    I have extensively used explicit waits in the test suite to poll for a certain element and proceed only if it was found. Most commonly it is used in conjuntion with EC (Expected Condition)

    Example code-

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    driver = webdriver.Firefox()
    driver.get("https://www.google.co.in/")
    try:
       WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID,"element")))
    except:
       pass
    

    Above code waits until 10 seconds before throwing a TimeoutException

    I have defined the default waiting time before throwing a timeout error as 60 seconds.

Time Required - It mostly depends on internet and processor speed. Generally the test suite takes about 3-5 minutes in executing all the tests.s

Comments