Skip to content

Use pytest to run our tests on Browserstack

Indira Nellutla edited this page Mar 5, 2018 · 1 revision

Configuring and integrating your tests to use pytest and BrowserStack by following the step by step guide and the detailed code samples.

In our framework, 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.

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 py.test command.

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")

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.

How to run a test on Browserstack

You can modify your tests to work well with BrowserStack and pytest. Let us try running an example test to check the browser title and test the form in Qxf2-selenium-tutorial-page on Browserstack using pytest.

Below snippet is required to get a webdriver and set useful capabilities:

#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)

The get_webdriver method gets the browser,browser_version,platform,os_version sets them as the desired capabilities and returns the appropriate webdriver.

The sample tests to checkout the pytest and BrowserStack integration

def test_example_form(base_url,browser,browser_version,os_version,os_name,remote_flag,testrail_flag,test_run_id):
    "Run the test"
    try:
	#Initalize flags for tests summary
        expected_pass = 0
        actual_pass = -1

        #1. Create a test object and fill the example form.
        test_obj = PageFactory.get_page_object("Main Page",base_url=base_url)

        #2. Setup and register a driver
        start_time = int(time.time())	#Set start_time with current time
        test_obj.register_driver(remote_flag,os_name,os_version,browser,browser_version)
        
        #3. Setup TestRail reporting
        if testrail_flag.lower()=='y':
            if test_run_id is None:
                test_obj.write('\033[91m'+"\n\nTestRail Integration Exception: It looks like you are trying to use TestRail Integration without providing test run id. \nPlease provide a valid test run id along with test run command using -R flag and try again. for eg: pytest -X Y -R 100\n"+'\033[0m')
                testrail_flag = 'N'   
            if test_run_id is not None:
                test_obj.register_testrail()
        
        #4. Get the test details from the conf file
        name = conf.name
        email = conf.email
        phone = conf.phone_no
        gender = conf.gender
 
        #5. Set name in form
        result_flag = test_obj.set_name(name) 
        test_obj.log_result(result_flag,
                            positive="Name was successfully set to: %s\n"%name,
                            negative="Failed to set name: %s \nOn url: %s\n"%(name,test_obj.get_current_url()))
        test_obj.write('Script duration: %d seconds\n'%(int(time.time()-start_time))) 
        #Update TestRail
        case_id = testrail_file.test_example_form_name
        test_obj.report_to_testrail(case_id,test_run_id,result_flag)

        #6. Set and submit the form in one go
        result_flag = test_obj.submit_form(name,email,phone,gender)
        test_obj.log_result(result_flag,
                            positive="Successfully submitted the form\n",
                            negative="Failed to submit the form \nOn url: %s"%test_obj.get_current_url())
        #Update TestRail
        case_id = testrail_file.test_example_form
        test_obj.report_to_testrail(case_id,test_run_id,result_flag)

        #7. Check the heading on the redirect page
        #Notice you don't need to create a new page object!
        if result_flag is True:
            result_flag = test_obj.check_heading()
        test_obj.log_result(result_flag,
                            positive="Heading on the redirect page checks out!\n",
                            negative="Fail: Heading on the redirect page is incorrect!")
        test_obj.write('Script duration: %d seconds\n'%(int(time.time()-start_time)))

        #8. Print out the results
        test_obj.write_test_summary()

        #Teardown
        test_obj.wait(3)
        expected_pass = test_obj.result_counter
        actual_pass = test_obj.pass_counter
        test_obj.teardown() 
        
    except Exception,e:
        print "Exception when trying to run test:%s"%__file__
        print "Python says:%s"%str(e)

    assert expected_pass == actual_pass