Qxf2 has been using popular cross-browser tools like BrowserStack and Sauce Labs for long. Recently, we integrated the LambdaTest tool also with our Page Object Model Framework. So we thought to write about it.
In this post, we will guide you through the process of running automation tests on LambdaTest using pytest. We will cover everything from setting up your LambdaTest account, configuring your test environment, writing automated test with pytest and running these tests on LambdaTest. By the end of this post, you will have a clear understanding of how to leverage LambdaTest for executing cross-browser tests efficiently and effectively.
How to run automation test on LambdaTest:
To run automation tests on LambdaTest, you need to follow below steps:
1) Register on LambdaTest and get accesskey
2) Configure pytest
3) Get LambdaTest webdriver
4) Write a simple test to run on LambdaTest
5) Run test on LambdaTest
Register on LambdaTest and get accesskey:
Navigate to LambdaTest and Sign up. Once you successfully open your account, log in to your account. Go to “Settings” > “Account Settings” > “Password and Security” and get your access key and username. This username and access_key is required for running tests on LambdaTest. We need it in upcoming section.
Configure pytest:
To run tests on LambdaTest, we need to provide below information:
1. os_name
2. os_version
3. browser
4. browser_version
5. remote_project_name
6. remote_build_name
Good to pass the above information as a command line parameter to pytest as we need to keep on changing this value as per our need. To add a command line parameter to pytest, we need to add a pytest option and a fixture to tie the option with it under conftest.py. Create or update conftest.py with the following lines of code for each option.
@pytest.fixture def browser(request): "pytest fixture for browser" return request.config.getoption("--browser") def pytest_addoption(parser): "Method to add the option to ini." try: parser.addoption("--browser", dest="browser", default="chrome", help="Browser. Valid options are firefox, ie and chrome") except Exception as e: print("Exception when trying to run test: %s"%__file__) print("Python says:%s"%str(e)) |
Similarly, you can write command line options for browser_version, os_name, os_version, remote_project_name and remote_project_build.
Look at the complete conftest.py file below:
Note: This is highly simplified code to make this post illustrative. We do not use this quality of the code at clients.
#Content on conftest.py import pytest @pytest.fixture def browser(request): "pytest fixture for browser" return request.config.getoption("--browser") @pytest.fixture def browser_version(request): "pytest fixture for browser version" return request.config.getoption("--ver") @pytest.fixture def os_name(request): "pytest fixture for os_name" return request.config.getoption("--os_name") @pytest.fixture def os_version(request): "pytest fixture for os version" return request.config.getoption("--os_version") @pytest.fixture def remote_project_name(request): "pytest fixture for project name" return request.config.getoption("--remote_project_name") @pytest.fixture def remote_build_name(request): "pytest fixture for build name" return request.config.getoption("--remote_build_name") @pytest.fixture def testname(request): "pytest fixture for testname" name_of_test = request.node.name name_of_test = name_of_test.split('[')[0] return name_of_test def pytest_addoption(parser): "Method to add the option to ini." try: parser.addoption("--browser", dest="browser", default="chrome", help="Browser. Valid options are firefox, ie and chrome") parser.addoption("--ver", dest="browser_version", help="The version of the browser: a whole number", default="125") parser.addoption("--os_name", dest="os_name", help="The operating system: Windows, Linux", default="Windows") parser.addoption("--os_version", dest="os_version", help="The operating system: xp, 7", default="10") parser.addoption("--remote_project_name", dest="remote_project_name", help="The project name if its run in BrowserStack", default=None) parser.addoption("--remote_build_name", dest="remote_build_name", help="The build name if its run in BrowserStack", default=None) except Exception as e: print("Exception when trying to run test: %s"%__file__) print("Python says:%s"%str(e)) |
Get LambdaTest webdriver:
From the above step, we will get details about os, os_version, browser, browser_version on which we need to run the test and what will be the name of the test, the project name and the build name. Now we need to use this information to configure LambdaTest Webdriver correctly.
Create a Python file with the name lambdatest_runner.py and keep the below code in it. You can directly use this script in your automation framework also, we neatly wrote it. The below script sets the webdriver correctly to run the test on the provided os, os_version, browser and browser_version and sets the default capabilities along with provided session test name, project name and build name. And returns the webdriver and session_url where you can see the test video and other details.
Note: This is highly simplified code to make this post illustrative. We do not use this quality of the code at clients.
# Content of lambdatest_runner.py """ Get the webdriver for LambdaTest browsers. """ import os import time import requests from selenium import webdriver from selenium.webdriver.firefox.options import Options as FirefoxOptions from selenium.webdriver.ie.options import Options as IeOptions from selenium.webdriver.chrome.options import Options as ChromeOptions class LambdaTestRunner(): """Configure and get the webdriver for the LambdaTest""" def __init__(self): self.username = os.getenv('REMOTE_USERNAME') self.password = os.getenv('REMOTE_ACCESS_KEY') lambdatest_url = "http://{}:{}@hub.lambdatest.com/wd/hub" self.lambdatest_url = lambdatest_url.format(self.username, self.password) self.lambdatest_api_server_url = "https://api.lambdatest.com/automation/api/v1" self.session_id = None self.session_url = None @staticmethod def firefox(browser_version): """Set web browser as firefox.""" options = FirefoxOptions() options.browser_version = browser_version return options @staticmethod def explorer(browser_version): """Set web browser as Explorer.""" options = IeOptions() options.browser_version = browser_version return options @staticmethod def chrome(browser_version): """Set web browser as Chrome.""" options = ChromeOptions() options.browser_version = browser_version return options def get_browser(self, browser, browser_version): """Select the browser.""" if browser.lower() == 'ff' or browser.lower() == 'firefox': desired_capabilities = self.firefox(browser_version) elif browser.lower() == 'ie': desired_capabilities = self.explorer(browser_version) elif browser.lower() == 'chrome': desired_capabilities = self.chrome(browser_version) else: print(f"\nDriverFactory does not know the browser\t{browser}\n") desired_capabilities = None return desired_capabilities def lambdatest_credentials(self, lambdatest_options): """Set LambdaTest credentials.""" lambdatest_options['user'] = self.username lambdatest_options['accessKey'] = self.password return lambdatest_options def set_lambdatest_capabilities(self,remote_project_name, remote_build_name, testname): """Set LambdaTest Capabilities""" lambdatest_options = {} lambdatest_options = self.lambdatest_credentials(lambdatest_options) lambdatest_options["build"] = remote_build_name lambdatest_options["project"] = remote_project_name lambdatest_options["name"] = testname lambdatest_options["video"] = True lambdatest_options["visual"] = True lambdatest_options["network"] = True lambdatest_options["w3c"] = True lambdatest_options["console"] = True lambdatest_options["plugin"] = "python-pytest" return lambdatest_options def get_lambdatest_webdriver(self, os_name, os_version, browser, browser_version, remote_project_name, remote_build_name, testname): """Run the test in LambdaTest when remote flag is 'Y'.""" options = self.get_browser(browser, browser_version) if options is None: raise ValueError(f"Unsupported browser: {browser}") # Set LambdaTest platform options.platformName = f"{os_name} {os_version}" lambdatest_options = self.set_lambdatest_capabilities(remote_project_name,remote_build_name, testname) options.set_capability('LT:options', lambdatest_options) web_driver = webdriver.Remote(command_executor=self.lambdatest_url, options=options) # Get the session ID and session URL and print it self.session_id = web_driver.session_id self.session_url = self.get_session_url_with_retries(self.session_id) return web_driver,self.session_url def get_session_url_with_retries(self, session_id, retries=5, delay=2, timeout=30): """Fetch the session URL using the LambdaTest API with retries.""" api_url = f"{self.lambdatest_api_server_url}/sessions/{session_id}" time.sleep(2) for _ in range(retries): response = requests.get(api_url, auth=(self.username, self.password),timeout=timeout) if response.status_code == 200: session_data = response.json() test_id = session_data['data']['test_id'] session_url = f"https://automation.lambdatest.com/test?testID={test_id}" return session_url else: print(f"Retrying... Status code: {response.status_code}, Response: {response.text}") time.sleep(delay) raise Exception(f"Failed to fetch session details after {retries} retries.") |
Write a simple test to run on LambdaTest:
In the above sections, we set a few command line parameters which are required to configure the LambdaTest web driver and we have a script to configure the Lambdatest web driver correctly. Now, in this section, we need to write a simple test to run on the LambdaTest.
Look at the below code, we wrote a simple pytest which creates a driver object using lambdatest_runner.py and prints the session URL and other platform details where it is running. We can navigate to this session URL to see the run. Test navigates to Qxf2’s tutorial page and verifies the title.
Note: This is highly simplified code to make this post illustrative. We do not use this quality of the code at clients. Our framework uses the Page Object pattern.
Look at test test_example_form.py below.
#Contents of test_example_form.py #NOTE: This is highly simplified code to make this post illustrative #We do not use this quality of the code at clients #Our framework uses the Page Object pattern from lambdatest_runner import LambdaTestRunner def test_example_form(os_name, os_version, browser, browser_version, remote_project_name, remote_build_name, testname): "Test example form" #Create an driver object runner = LambdaTestRunner() driver,session_url = runner.get_lambdatest_webdriver(os_name, os_version, browser, browser_version, remote_project_name, remote_build_name, testname) print("\nRunning test on LambdaTest Platform") print("Session url:",session_url) #Create variables to keep count of pass/fail pass_check_counter = 0 total_checks = 0 #Visit the tutorial page driver.get('http://qxf2.com/selenium-tutorial-main') print("Browser: ",browser) print("Browser version: ",browser_version) print("OS: ",os_name) print("OS version: ",os_version) print("\nNavigated to Qxf2's Selenium Tutorial page") #Check 1: Is the page title correct? total_checks += 1 if(driver.title=="Qxf2 Services: Selenium training main"): print("Success: Title of the Qxf2 Tutorial page is correct") pass_check_counter += 1 else: print("Failed: Qxf2 Tutorial page Title is incorrect") #Quit the browser window driver.quit() #Assert if the pass and fail check counters are equal assert total_checks == pass_check_counter |
Run the test on LambdaTest:
Now we have 3 files conftest.py (to configure test), lambdatest_runner (configure and get LambdaTest webdriver) and test file test_example_form.py. To run test test_example_form we can use the below command:
pytest -s -v --browser firefox --ver 120 --remote_project_name Qxf2_Selenium_Blog_Test --remote_build_name LambdaTest_Blog |
Along with the above command, you can also pass the os and os versions with –os_name and –os_version params respectively. By default, it is set to Windows 10.
Look at the test run logs in the below screenshot.
You can navigate to the provided session URL in logs to watch the test video. Look at the LambdaTest web automation page below.
Hope this blog helps you to get set with LambdaTest for your automation framework. At Qxf2, we integrated our Page Object Model framework with the LambdaTest. You can refer to our framework readme file for setup and run the test using the below command.
pytest tests/test_example_forms.py -s -v --remote_flag y |
With the correct setup and the above command, test run on the LambdaTest and update test run status also. We will cover how to update the test run status on the LambdaTest web automation page in our upcoming blog.
Hire Qxf2 for your testing needs
Qxf2 is the home of the technical tester. Since 2013, we’ve been early adopters of new testing techniques and tools, staying abreast of technical trends. We offer unique services tailored to small engineering teams building early stage products. You can get in touch with us to learn more about our offerings.
I love technology and learning new things. I explore both hardware and software. I am passionate about robotics and embedded systems which motivate me to develop my software and hardware skills. I have good knowledge of Python, Selenium, Arduino, C and hardware design. I have developed several robots and participated in robotics competitions. I am constantly exploring new test ideas and test tools for software and hardware. At Qxf2, I am working on developing hardware tools for automated tests ala Tapster. Incidentally, I created Qxf2’s first robot. Besides testing, I like playing cricket, badminton and developing embedded gadget for fun.