BrowserStack is a cloud-based testing tool that enables developers/testers to test their application across various browsers on different operating systems and mobile devices. We use Browserstack a lot at Qxf2 and recommend it to all our clients. We recently started using pytest to run our tests. We were surprised how quick and easy it was to configure pytest to run our tests on Browserstack. We have decided to share how we were able to do it.
BrowserStack needs four pieces of information to start a test:
a) the browser
b) the browser version
c) the operating system
d) the operating system version
In this post, we’ll show you how to add these four pieces of information as command line parameters to pytest. While the task at hand is direct, we thought this topic would make a good backdrop for you to learn more about pytest. So throughout this blog post, we have sprinkled in some useful tips that will help you get comfortable with pytest. If you do not understand some of the terms we use – it’s ok! You can still integrate your tests to use pytest and BrowserStack by following the step by step guide and the detailed code samples.
How to configure pytest to work with BrowserStack
pytest can be configured to suit our testing needs. It implements all aspects of configuration, collection, running and reporting. For our problem, there is one term in pytest land that you need to become familiar with – fixtures. A test fixture is simply something that a test must (or may) need to know before it can be executed from a known state. We are going to treat each independent piece of information that BrowserStack requires (e.g.: browser, browser version) as pytest fixtures. Fixtures can be created for the parameters that are being used in the test function. These fixtures can be held in the test file or be held in a special
conftest.py file separately. The perk of having fixtures in a
conftest.py is that it can be used by my multiple tests.
1. Create a conftest.py file
To begin with, create a file called
conftest.py and place it in the root directory of your repository or code base. Your root directory is going to be the directory from which you kick off the
2. Add a command line parameter to conftest.py
#Contents of the conftest.py file def pytest_addoption(parser): parser.addoption("-B","--browser", dest="browser", default="firefox", help="Browser. Valid options are firefox, ie and chrome")
3. Add a fixture to conftest.py
@pytest.fixture def browser(): "pytest fixture for browser" return pytest.config.getoption("-B") #Note how this ties to the newly added command line parameter
Everytime pytest sees
browser as the test function parameter it executes the pytest fixture which looks if any command line parameter has been provided, if no option is given pytest uses the default option that was mentioned when the option was added.
We are almost done! Once you setup your
conftest.py to take in the browser version, os and os version – you are done with configuring pytest. You can see the completed conftest file (has fixtures for all four pieces of information that BrowserStack needs) in the ‘Putting it all together section’.
How to run a test on Browserstack
In this section we will show you how to modify your test so it works well with BrowserStack and pytest. Let us try running an example test to check the browser title and test the form in the Qxf2-selenium-tutorial-page on Browserstack using pytest.
#NOTE: This is highly simplified code to make this post illustrative #We do not use this code at clients #We use Driver_Factory to return apporpriate drivers within our framework def get_webdriver(browser,browser_version,platform,os_version): "Run the test in browser stack browser stack flag is 'Y'" USERNAME = usename #We fetch values from a conf file in our framework we use on our clients PASSWORD = accesskey if browser.lower() == 'firefox': desired_capabilities = DesiredCapabilities.FIREFOX if browser.lower() == 'chrome': desired_capabilities = DesiredCapabilities.CHROME desired_capabilities['os'] = platform desired_capabilities['os_version'] = os_version desired_capabilities['browser_version'] = browser_version return webdriver.Remote(command_executor='http://%s:%[email protected]:80/wd/hub'%(USERNAME,PASSWORD), desired_capabilities=desired_capabilities)
get_webdriver method gets the browser,browser_version,platform,os_version sets them as the desired capabilities and returns the appropriate webdriver.
Putting it all together:
We are including a sample test for you to checkout the pytest and BrowserStack integration. The test script looks like the code below:
#NOTE: This is highly simplified code to make this post illustrative #We do not use this code at clients #Our framework uses the Page Object pattern #Contents of test_example_form.py def test_example_form(browser,browserstack_flag,browser_version,platform,os_version): "Test example form" #Create an driver object driver = get_webdriver(browser,browser_version,platform,os_version) #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 "The browser for this test it %s"%browser print "The browser version is %s"%browser_version print "The platform is %s"%platform print "The os version is %s"%os_version #Check 1: Is the page title correct? if(driver.title=="Qxf2 Services: Selenium training main"): print "\n" print ("Success: Title of the Qxf2 Tutorial page is correct") pass_check_counter += 1 else: print ("Failed: Qxf2 Tutorial page Title is incorrect") total_checks += 1 #Check 2: Fill name, email and phone in the example form total_checks += 1 name_field = driver.find_element_by_xpath("//input[@type='name']") name_field.send_keys('Shivahari') email_field = driver.find_element_by_xpath("//input[@type='email']") email_field.send_keys('[email protected]') phone_field = driver.find_element_by_xpath("//input[@type='phone']") phone_field.send_keys('9999999999') submit_button = driver.find_element_by_xpath("//button[@type='submit']") #Click on the Click me button try: submit_button.click() pass_check_counter += 1 except Exception,e: print str(e) #Quit the browser window driver.quit() #Assert if the pass and fail check counters are equal assert total_checks == pass_check_counter
conftest.py looks like this:
#Contents of conftest.py import pytest import os @pytest.fixture def browser(): "pytest fixture for browser" return pytest.config.getoption("-B") @pytest.fixture def browserstack_flag(): "pytest fixture for browserstack flag" return pytest.config.getoption("-M") @pytest.fixture def browser_version(): "pytest fixture for browser version" return pytest.config.getoption("-V") @pytest.fixture def platform(): "pytest fixture for platform" return pytest.config.getoption("-P") @pytest.fixture def os_version(): "pytest fixture for os version" return pytest.config.getoption("-O") def pytest_addoption(parser): parser.addoption("-B","--browser", dest="browser", default="firefox", help="Browser. Valid options are firefox, ie and chrome") parser.addoption("-M","--browserstack_flag", dest="browserstack_flag", default="N", help="Run the test in Browserstack: Y or N") parser.addoption("-V","--ver", dest="browser_version", help="The version of the browser: a whole number", default=45) parser.addoption("-P","--platform", dest="platform", help="The operating system: Windows 7, Linux", default="Windows") parser.addoption("-O","--os_version", dest="os_version", help="The operating system: xp, 7", default="7")
Run the test:
To run the test use the command
You can run this test on a different platform (say OS X Yosemite) using a different browser (say Chrome 50) by using the command:
py.test -B chrome -V 50 -P "OS X" -O Yosemite -M y
There you go,a detailed example to configure pytest and run tests on browserstack. Now try running the tests across different platforms,platform version,browsers and browser versions.
If you liked what you read, know more about Qxf2.