Home Tech Top 13 Best Practices For Selenium Testing

Top 13 Best Practices For Selenium Testing

1309
testing

There are a number of benefits of performing testing at an early stage of product development. Out of all the benefits, the major benefit is detection & resolution of bugs at an early stage. Developers have to verify their code by writing effective unit tests that verify each and every unit of the code. Unit testing is an integral part of the agile development process, as well as Test Driven development and helps in building robust software components. If code issues are not resolved at a unit level or go unnoticed at a unit level, the cost & effort for fixing the bug could be more as they are detected at a later stage. Hence, developers should come up with effective unit tests in order to verify their implementation.

Test automation can be used in order to accelerate the test process and coming up with test cases that cover different scenarios. We have already covered different frameworks and test approaches in our earlier blogs that focus on test automation with Selenium Python. As far as automation testing in Python is concerned, test frameworks like Pytest, Unittest, Robot, etc. can be used along with Selenium for test development & automation. It might be impossible to achieve 100% test automation but choosing the right tools, test frameworks, test structure, etc. can definitely reap long-term benefits. Though the term right can be used subjectively as the tools & frameworks being used depend on the type & scale of the project, there are some common best practices or guidelines when you are doing unit testing in Python. Before we deep dive into test automation with Selenium Python or automation testing in Python, let’s have a look at some of the generic principles related to automation testing at a unit level. 

Incorporate Test Automation at an early stage

As mentioned earlier, you cannot achieve 100% automation for designing & writing unit tests. Hence, it becomes an important task to identify the potential test cases that can be automated. A test case that is triggered for minimal number of times should not be automated since there are minimal benefits in doing the same. On the other hand, test cases that are executed numerous times and take number of inputs (as test data) can be considered as ideal candidates for test automation. This principle can be applied irrespective of whether your team us using test automation with Selenium Python or any other framework for testing.

  • You should automate tests that fall in either of these categories
  • Test cases that make use of large data sets as input.
  • Test cases that are prone to manual errors or difficult to perform manually.
  • Test cases that are need to be tested on different test environments e.g. different combinations of browsers, operating systems, devices, etc.
  • Test cases that are repetitive in nature.

Before you start automation testing, you should have a concrete test automation plan. This plan can be used as a running document for planning & execution of automation tests. Carefully design actions that need to be performed by the automated tests. Development and maintenance of a single test suite (that contains different test cases) can become a daunting task. Hence, it is important to break your test suite/test cases in smaller logical parts since it eases the job of test development & maintenance. You can also make use of Page Object Model (POM) to isolate test cases from web elements/web locators so that changes in GUI/UI have minimal impact on testing.

Deploy Shift-Left Testing approach

As mentioned in the earlier point, it is always beneficial to start testing; specifically automation testing at a very early stage. The respective teams should look for scenarios which can be automated so that less ‘manual effort’ is spent on testing and more on ‘automation’. The intention should be to build a robust automation test suite which requires minimal code changes even though there are frequent changes in the UI.

It is important to involve testers at an early phase of product development and this is where shift-left testing or continuous delivery testing can be instrumental in making the most out of testing. Unlike traditional testing approach, with shift-left testing; testing is not performed in isolation but it is done in sync with the product/project development.

Since the test team works in close co-ordination with the other stakeholders of the project, bugs can be reported as well as resolved at a much faster pace. Depending on the scope & scale of the project, you can also plan transitioning to DevOps so that you can make the best out of Shift-Left & Shift-Right testing.

Select the ‘appropriate’ test automation Arsenal

Since there are a number of test automation tools available in the market, it is very important that you do a careful analysis of each tool, in terms of scalability, performance, and pricing. If your product would be used by global consumers/customers, you should opt for a good cross-browser testing tool so that the code can be verified on different combinations of browsers, platforms, and operating systems. You may want to check if the tool supports playback & record testing and effort involved in porting the local test code on to their test platform.

There are many other points that you should consider namely – ease of use of the test tool, support for different automation test frameworks like Selenium, creation of robust automation test suite/test code which has minimal dependencies on UI changes, following uniform naming convention for folders, test suites, test cases, etc. and usage of extensive test data set in order to achieve maximum test coverage. Now that we have looked into the generic testing guidelines, let us have a detailed look at unit testing guidelines for test automation with Selenium Python.

Usage of one assert per test

A unit test should focus on testing a particular functionality hence, it is important to keep the logic of unit tests less complicated. An assertion is normally used to halt the further execution of the test code in case an error is encountered. Depending on the test requirements, you need to make a choice whether to issue an assert or continue the execution. Many unit tests have multiple asserts in the test code which makes it more difficult to maintain. 

Large test cases should be broken into smaller ones so that maintenance is easy. It is recommended to have one assert per test and a logical description that describes the intent of the assert should be added. This helps in identifying the test suite/test case that caused assert by just locating that assert in the test code. In the example below, a pop-window is opened and an assert is issued if the window title does not match with the expected title. The code is maintainable and has asserts issued at the right places in the test.

FileName – test_1_assert.py  

import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By

class AssertTest(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Firefox()

    def test_assert_on_title(self):
        driver = self.driver
        driver.get(“http://www.quackit.com/html/codes/html_popup_window_code.cfm”)
        str1 = driver.title
        print(str1)

        # get the window handles using window_handles() method
        window_before = driver.window_handles[0]
        print(window_before)

        # since the pop-up is now in an iframe
        driver.switch_to.frame(driver.find_element_by_name(‘result1’))
        driver.find_element_by_link_text(‘Open a popup window’).click()

        # get the window handle after a new window has opened
        window_after = driver.window_handles[1]

        # switch on to new child window
        driver.switch_to.window(window_after)
        str2 = driver.title
        print(str2)
        print(window_after)

        # assert that main window and child window title don’t match
        self.assertNotEqual(str1, str2)
        print(‘This window has a different title’)

        # switch back to original window
        driver.switch_to.window(window_before)

        # assert that the title now match
        self.assertEqual(str1, driver.title)
        print(‘Returned to parent window. Title now match’)

    def tearDown(self):
        self.driver.close()


if __name__ == “__main__”:
    unittest.main()

Cleanup after test execution

A testsuite is a collection of test cases which are executed as a part of the test cycle. In test automation with Selenium Python, test cases are passed to the TestSuite() method which also determines the sequence of execution. There might be a scenario where some test cases take longer time for execution hence; such test cases can be grouped in a separate test suite that is run by some scheduled task. This ensures that the heavier tests do not hinder the execution of the remaining test cases/test suites which requires fewer resources.

Each test case should be loaded with a fresh dataset else the test might give incorrect results. A cleanup activity should be performed after execution of each test case/test suite. Clean-up is normally done in the tearDown() method and initialization/set-up is done in the setUp() method. For example, if your testsuite has two test cases (TCs) where TC-1 uses Chrome browser for testing and TC-2 uses Firefox browser for testing, the test cases should free the resources consumed by those browsers in the tearDown() method along with destroying the browser instance. In the example below, a Google Search is performed on the Firefox browser. driver.close() and driver.quit() APIs are used to perform a cleanup activity.

import unittest
from selenium import webdriver
import time
from time import sleep
import warnings
import urllib3

class GoogleSeachTest(unittest.TestCase):
    def setUp(self):
        global remote_url

        urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

    def test_GoogleSearch(self):
        driver_chrome = webdriver.Chrome()
        self.driver = driver_chrome
        driver_chrome.maximize_window()
        driver_chrome.get(‘http://www.google.com’)

        # Perform search operation
        elem = driver_chrome.find_element_by_name(“q”)
        elem.send_keys(“Lambdatest”)
        elem.submit()

    def tearDown(self):
        # Close the browser.
        self.driver.close()
        self.driver.quit()

if __name__ == ‘__main__’:
    unittest.main()

Usage of hard-coded values

Over the course of the project, there would be number of changes in the UI or core logic of the web-app/website. Just like implementation source code should not have hard-coded values, the test code should also not contain hard-coded values.

Variables should be used whenever required and those variables should be stored in a separate file. This file can be included as a module in the core Python test file which contains the actual implementation. This can also be applied to web element locators which are used for UI testing. The entire practice helps in reducing the effort spent in code changes if there are any changes in UI or variables need to be changed.

Make the right web locators to work

The main use of the Selenium framework is to automate the interaction with the underlying web elements/locators in a web page. There are number of locators like CSS locator, ID/Name, XPath, Link text, Tag name, etc. Hence, while automating the interaction with the web element, you need to choose the best-suited web element in terms of discoverability and performance.

You should make use of the Inspect Tool in Chrome/Firefox browser to determine the object. Class or ID/Name elements are easy to locate and also help in improving the performance of the test code. They can be used in case you do not intend to keep the developer or test team informed about the changes. Interacting with a web element via XPath can turn out to be slow in some browsers but sometimes that is easiest way to locate the element. XPath should be used when the element is loaded dynamically i.e. when the page uses AJAX (Asynchronous JavaScript and XML). Link Text can also be used in case performance is a priority but your test code may undergo changes in case the link text changes on a frequent basis.

In the below example, the AUT is http://www.lambdatest.com and XPath of the Login button is used to automate the click operation.

import unittest
from selenium import webdriver
import time
from time import sleep
import urllib3

# Use the Inspect option in the browser to locate the Login element
lt_login_button = “//*[@id=’bs-example-navbar-collapse-1′]/ul/li[6]/a”

class test_WebElementDemo(unittest.TestCase):
    def setUp(self):
        global remote_url

        urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

    def test_webelement_click(self):
        driver_chrome = webdriver.Chrome()
        self.driver = driver_chrome
        driver_chrome.maximize_window()
        driver_chrome.get(‘http://www.lamdatest.com’)

        time.sleep(10)

        elem = driver_chrome.find_element_by_xpath(lt_login_button)

        # Perform Click operation
        elem.click()
        time.sleep(20)

    def tearDown(self):
        # Close the browser.
        self.driver.close()
        self.driver.quit()

if __name__ == ‘__main__’:
    unittest.main()

Choosing the best web selectors for the job

We have already discussed about the importance & role of web selectors in order to automate the interaction with the underlying web element on a page. When you are doing automation testing with Python, making use of the most appropriate web element/selector can make a huge difference as far as performance is concerned. When doing test automation with Selenium Python, you need to choose a Selector Order.

A web locator which is based on location will be slowest to locate the element. XPath and CSS fall under this category. CSS is normally a combination of ID and Name. Hence, these should be considered as the last priority. Web locators that use text or ID to locate elements yield better performance results. ID, Name, and Link text should be considered before XPath and CSS. We have covered web selectors and their usage in more detail in our earlier blogs. The best approach to search for a web element in AUT can be 1. ID 2. Name 3. Link Text 4. CSS 5. XPath.

Wrapping Selenium Calls using webdriverwrapper and seleniumwrapper

There could be cases where you have used more or less similar code to interact with the web element when using test automation with Selenium Python. It could either be locating a web element, performing a click operation, click and wait, etc. Rather than using repetitive code (with minimal changes), you can create methods for these frequently used tasks and that method can be used instead of the repetitive code. This helps in making the code cleaner & maintainable and also reduces the overall code size.

Though you can create your own methods, WebDriver Wrapper can be used for making the most out of unit testing in Python. WebDriver wrapper is better interface of WebDriver in Python. It is a wrapper around frequently used Selenium WebDriver calls e.g. Creation of WebDriver instance, finding elements, filling out forms using fill_out(), etc. It provides TestCase for unit testing and pytest fixtures for testing with pytest framework. In order to install webdriverwrapper and seleniumwrapper, you need to execute the following commands on the terminal

pip install webdriverwrapperpip install seleniumwrapper

Please refer the official documentation of webdriverwrapper and official documentation of Selenium Wrapper for more information on the respective packages/modules. For demonstration, we use the webdriverwrapper for performing Login on the LambdaTest website.

import unittest
from selenium import webdriver
import webdriverwrapper
from webdriverwrapper import Chrome
from webdriverwrapper import Firefox
import seleniumwrapper as selwrap
import time
from time import sleep
import urllib3

# Use the Inspect option in the browser to locate the Login element
lt_login_button = “//*[@id=’bs-example-navbar-collapse-1′]/ul/li[6]/a”

# Refer http://horejsek.github.io/python-webdriverwrapper/ for more information on webdriverwrapper
# Refer https://pypi.org/project/seleniumwrapper/ for more information on seleniumwrapper

class test_seleniumwrapper_demo(unittest.TestCase):
    def setUp(self):
        global remote_url

        urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

    def test_webelement_click(self):
        #driver_chrome = webdriver.Chrome()
        #self.driver = driver_chrome
        #driver_chrome.maximize_window()
        driver_chrome = Chrome()
        self.driver = driver_chrome
        driver_chrome.maximize_window()
        driver_chrome.get(‘http://www.lamdatest.com’)

        time.sleep(10)

        elem = driver_chrome.get_elm(xpath=lt_login_button)

        # Perform Click operation
        elem.click()
        time.sleep(20)

    def tearDown(self):
        # Close the browser.
        self.driver.close()
        self.driver.quit()

if __name__ == ‘__main__’:
    unittest.main()

Select the Python test framework that suits your requirements

Apart from unittest/Pyunit, there are many other test frameworks in Python. Some of the most prominent test frameworks to achieve unit testing in Python or automation testing in Python are Pytest, Robot, Lettuce, Behave, etc. Depending on the scope & budget of testing, your team needs to select the best suited framework for development of test code/test suite. For test automation in Selenium Python, you can also use a mix of all these test frameworks to achieve the best possible test coverage results.

There is a detailed article on Pros, Cons, and requirements for usage of the test automation frameworks which can be referred here. The Pytest test framework can be used to perform property based testing when used along with Hypothesis library. Hypothesis can be used with Python & Selenium WebDriver to test your code against different range of input values with minimal implementation effort. The range of test data is automatically generated hence it can be used in place of parameterized fixtures in Pytest in some scenarios.

Shown below is an example that showcases the usage of Pytest framework with Hypothesis library in order to perform cross-browser testing. The different inputs are supplied to the test code using the strategy module. You have to compile the test code using the command py.test –capture=no –hypothesis-show-statistics <file-name.py>

import pytest
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
from time import sleep
import urllib3
import warnings

class CrossBrowserSetup(object):
    global web_driver

    def __init__(self):
        global remote_url

        urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

    def add(self, browsertype_1, browsertype_2):
        print(browsertype_1)
        print(browsertype_2)
        if (browsertype_1 == “Chrome”) or (browsertype_2 == “Chrome”):
            web_driver = webdriver.Chrome()
            self.driver = web_driver
            web_driver.maximize_window()
            self.driver = web_driver
            self.driver.get(“https://www.lambdatest.com”)
            print(self.driver.title)
            sleep(5)
            web_driver.close()
            web_driver.quit()
        if (browsertype_1 == “Firefox”) or (browsertype_2 == “Firefox”):
            web_driver = webdriver.Firefox()
            self.driver = web_driver
            web_driver.maximize_window()
            self.driver = web_driver
            self.driver.get(“https://www.lambdatest.com”)
            print(self.driver.title)
            sleep(5)
            web_driver.close()
            web_driver.quit()

# Property-based Tests
import os
from hypothesis import given, example, settings
import hypothesis.strategies as strategy

@given(strategy.just(“Chrome”), strategy.just(“Firefox”))
# Set the deadline to None else it may result in 200ms timeout
@settings(deadline = None)

def test_add(browsertype_1, browsertype_2):
    cbt = CrossBrowserSetup()
    cbt.add(browsertype_1, browsertype_2)

To know more about the Hypothesis module, we recommend you to have a look at the detailed article which touches upon every aspect of Hypothesis, same can be found here. The Robot framework can be used to perform keyword-driven testing which makes the automation process simpler. Though there is a learning curve involved in understanding the keywords, Robot framework can be used to run Parallel tests via the Selenium Grid. Robot framework has a rich set of libraries using which you can come up with keyword-driven test cases/test suites with less effort. You can refer to our detailed blog which walks you through the Robot framework usage with Pytest, same can be found here.

To summarize, you should select the test framework that aligns with your project timelines and test requirements.

Using Page Object Model (POM) to avoid code duplication

During the course of the development of test code, there might be scenarios where the test code becomes less maintainable due to code duplication and inefficient usage of web locators that are scattered across different files. This is where Page Object Model (POM) can be used to solve the issue of code maintainability & minimize code duplication by separating storage of web locators from implementation of test cases/test suites. Hence, frequent changes in UI will only involve changes in the web locators without impacting the test implementation.

Test code implemented using any of the Python test frameworks can become more maintainable when used along with Page Object Model (POM). You should select the optimal directory structure to separate the test implementation from the web locators. Doing so makes the code more readable and usable. In test automation with Selenium Python, Page Object Model (POM) design pattern can be applied to any type of test framework and you can mix different test frameworks in one single test suite since the core test code implementation is separated from the storage of web locators.

Making a choice between Implicit Wait and Explicit Wait

A web page can consist of static as well as dynamic elements. Dynamic elements are loaded using AJAX where the entire web page is not completely reloaded but only few elements are loaded asynchronously without interfering with the display of the existing page. If your Selenium code is interacting with a web element that is not there in the DOM, it can result in errors. There are two options that can be used to handle elements that are loaded dynamically

Implicit Wait – An implicit wait makes the Selenium WebDriver to poll the DOM for certain duration. The default wait time is 0 seconds i.e. there is no wait in case the element is present/not present on the page. However, if the wait duration is specified via driver.implicitly_wait(no-of-seconds), a blocking wait is performed for those many seconds. Such kind of wait can cause delay in the execution of the test code that follows the implicit delay. Using implicit wait more often can have performance implications since every implicit wait adds up to the overall delay.

The example below demonstrates the use of Implicit Wait where blocking wait of 10 seconds each is used during the course of 2 operations.

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
from time import sleep
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait

driver = webdriver.Chrome()
driver.get(“https://www.lambdatest.com”)

myElem_1 = driver.find_element_by_class_name(‘home-btn’)
driver.implicitly_wait(10)
print(“Home Button click under progress”)
myElem_1.click()

myElem_2 = driver.find_element_by_xpath(“/html/body/div[1]/section/div/div[2]/div/form/div[3]/p/a”)
driver.implicitly_wait(10)
print(“Login button click under progress”)
myElem_2.click()

sleep(10)
print(“Cleanup in progress”)
driver.close()

Explicit Wait – An explicit wait waits on a certain condition to occur. The condition could be for a particular web element. Though the wait mentioned could be 10 seconds, there is a possibility that the web element (on which wait is performed) might be loaded in less than 10 seconds. In such cases, the wait will occur only for that much time duration. In case, the condition on which the wait is performed returns False i.e. it fails, an error is returned about the timeout of explicit wait condition.

In the example shown below, a wait of 10 seconds each is performed where the web elements ‘home-btn‘ and ‘login‘ are checked for clickability. If the web element is not available after 10 seconds, a TimeoutException is triggered.

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
from time import sleep
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait

driver = webdriver.Firefox()
driver.get(“https://www.lambdatest.com”)


try:
    myElem_1 = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, ‘home-btn’)))
    print(“Home Button click under progress”)
    myElem_1.click()

    myElem_2 = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, “/html/body/div[1]/section/div/div[2]/div/form/div[3]/p/a”)))
    print(“Login button click under progress”)
    myElem_2.click()
    sleep(10)
except TimeoutException:
    print(“No element found”)

sleep(10)

driver.close()

Using Fixtures for testing against multiple browsers

In our earlier point, we discussed about the different frameworks of Python and how you can leverage each framework to make the most out of unit testing in Python.  In order to verify your test code on different web browsers, you can make use of Fixtures in Pytest framework where browsers on which test needs to be performed can be passed as parameters.

You can make use of the Remote Selenium WebDriver interface to verify the test code on web browsers installed on a machine (that is connected to the network). The machine on which browsers are installed can be considered as Master/Server and requests are triggered via Remote WebDriver Interfaces (also called as Clients/Slaves). 

You can easily port implementation that uses local WebDriver interface to one that uses Remote WebDriver interface. In the example below, two params – Chrome & Firefox with scope as Class are passed as Fixtures.

# Import the ‘modules’ that are required for execution

import pytest
#import pytest_html
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
from time import sleep

#Fixture for Firefox
@pytest.fixture(params=[“chrome”, “firefox”],scope=“class”)
def driver_init(request):
    if request.param == “chrome”:
    #Local webdriver implementation
    #web_driver = webdriver.Chrome()
  #Remote WebDriver implementation
    web_driver = webdriver.Remote(
            command_executor=‘http://107.108.xx.xx:4444/wd/hub’,
            desired_capabilities={‘browserName’: ‘chrome’, ‘javascriptEnabled’: True})
    if request.param == “firefox”:
    #Local webdriver implementation
    #web_driver = webdriver.Firefox()

  #Remote WebDriver implementation
    web_driver = webdriver.Remote(
          command_executor=‘http://107.108.xx.xx:4444/wd/hub’,
          desired_capabilities={‘browserName’: ‘firefox’})
    request.cls.driver = web_driver
    yield
    web_driver.close()

@pytest.mark.usefixtures(“driver_init”)
class BasicTest:
    pass
class Test_URL(BasicTest):
        def test_open_url(self):
            self.driver.get(“https://www.lambdatest.com/”)
            print(self.driver.title)

            sleep(5)

There is also an option to use the Hypothesis framework in case you plan to use keyword-driven testing for verification. We have already demonstrated the usage of Hypothesis framework with the Selenium Grid to perform cross-browser testing.

Using reports for keeping track of test results

When performing automation testing in Python on a web project/product, you may want to keep a track of the test development (i.e. test code/test suite) as to how the code has evolved over a period of time. Along with it, keeping a track of the number of test cases passed, test scenarios implemented, records about the release on which the tests were performed, etc. can come very handy to track progress.

pytest-html is a module of the pytest framework that can be used to generate test reports. To get started, you need to install the pytest-html module using pip install pytest-html command on the terminal. To use the module, you have to import pytest-html module in the test code implemented using pytest.

import pytest_html

In order to generate reports, you have to append the below option while executing the pytest code.

-html=pytest_selenium_test_report.html

Cross-browser testing on the cloud

It is important to test your web product/web app against different combinations of web browsers, operating systems, and devices to ensure good user experience. Performing testing on different combinations using local machine i.e. local web-driver or remote web-driver i.e. in-house server that houses these combinations is not a scalable approach.

Hence, you can opt for a cross-browser testing on the cloud. This approach is more scalable and it also speeds up the entire automation testing process since you can make use of parallel execution. Using LambdaTest, automated and live interactive cross browser testing can be done on 2000+ real browsers and operating systems online. After creating an account on https://www.lambdatest.com/, you should make note of the user-name & access-token located in the profile section https://accounts.lambdatest.com/profile. Porting the existing test code for unit testing in Python to LambdaTest involves less effort since it supports usage of different Python test frameworks with Selenium. Once you set the required browser capabilities, execution is performed using the following command in the test code.

webdriver.Remote(command_executor=remote_url, desired_capabilities=ch_caps)
import unittest
from selenium import webdriver
import time
from time import sleep
import urllib3

# Use the Inspect option in the browser to locate the Login element
lt_login_button = “//*[@id=’bs-example-navbar-collapse-1′]/ul/li[6]/a”

############# Changes for porting local Selenium WebDriver implementation to LambdaTest #############
#Set capabilities for testing on Chrome
ch_caps = {
    “build” : “Sel-Grid-Chrome”,
    “name” : “Testing on Chrome using Selenium Grid (unit testing best practices)”,
    “platform” : “Windows 10”,
    “browserName” : “Chrome”,
    “version” : “71.0”,
    “selenium_version” : “3.13.0”,
    “chrome.driver” : 2.42
}

# Obtain the credentials from https://accounts.lambdatest.com/profile
user_name = “user-name”
app_key = “app_key”
class test_WebElementDemo(unittest.TestCase):
    def setUp(self):
        global remote_url

        urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
        remote_url = “https://” + user_name + “:” + app_key + “@hub.lambdatest.com/wd/hub”

    def test_webelement_click(self):
        web_driver = webdriver.Remote(command_executor=remote_url, desired_capabilities=ch_caps)
        #driver_chrome = webdriver.Chrome()
        self.driver = web_driver
        web_driver.maximize_window()
        web_driver.get(‘http://www.lamdatest.com’)

        time.sleep(10)

        elem = web_driver.find_element_by_xpath(lt_login_button)

        # Perform Click operation
        elem.click()
        time.sleep(20)

    def tearDown(self):
        # Close the browser.
        self.driver.close()
        self.driver.quit()

if __name__ == ‘__main__’:
    unittest.main()

To check the status of execution, you should visit the automation tab on the LambdaTest platform and select the test matching the build-name. Below is the screenshot of the automation test that was performed on LambdaTest.

https://lh6.googleusercontent.com/QmbuP3qIZ_fnRmFNtXBEWZjzataDfjjgfSCAXhR-D4GmTHEwym8RFGtyscLEnqoEQQhuXpSpys3mJGiUuskEH3D277ioSYCyNzuEtsKyU_g5vCWoOjZuk_YZQ7n6rX09ETMbd98

Conclusion

There are many test frameworks in Python can be used along with the Selenium WebDriver. As a developer, you should select the test framework that best suits your project requirements & timelines. Automation testing in Python will yield better results if best practices are followed while implementing the test code. In order to expedite the testing process on cross-browser platform, you should make use of cross-browser testing on the cloud as it is scalable & economical. Test automation with Selenium Python is widely used for testing and using efficient test guidelines can get better results out of testing.