Search by

Run your first test

BrowserStack App Automate enables you to test native and hybrid mobile applications using Appium automation framework. Its easy to run your Appium tests using Behave on real Android and iOS devices on BrowserStack. This guide will help you get started with your first test.

1. Setup

Ensure you have the Behave libraries installed.

# Install using pip
pip install behave

2. Upload your app

Upload your Android app (.apk or .aab file) or iOS app (.ipa file) to BrowserStack servers using our REST API. Here is an example cURL request to upload the app :

curl -u "YOUR_USERNAME:YOUR_ACCESS_KEY" \
-X POST "https://api-cloud.browserstack.com/app-automate/upload" \
-F "file=@/path/to/app/file/Application-debug.apk"

A sample response for the above request is shown below:

{
    "app_url":"bs://j3c874f21852ba57957a3fdc33f47514288c4ba4"
}

Note the value of app_url returned in the API response (bs://j3c874f21852b..... in the above example). This value will be used later to set the app capability to specify application under test in your Appium test scripts.

Note:
  1. App upload will take a few seconds to about a minute depending on the size of your app. Do not interrupt the cURL command until you get the response back.
  2. If you upload an iOS app, we will re-sign the app with our own provisioning profile to be able to install your app on our devices during test execution.

3. Configure and run the test

In this step, you will learn how to configure your Appium test script using desired capabilities to test remotely on BrowserStack’s real device cloud. Here is a sample test case written for running with Behave:

If you are using our Sample App, the sample test below will install the Sample App (Wikipedia App) on the device, search for ‘browserstack’ and asserts for the list of results. If you are using your own app, modify the code as per your test cases.

#Wikipedia Feature
Feature: Wikipedia Search Functionality
    Scenario: can find search results
        Given I open the app and search for keyword "BrowserStack"
        Then Search results should appear
@given(u'I open the app and search for keyword "{keyword}"')
def step_impl(context, keyword):
    search_element = WebDriverWait(context.browser, 10).until(
        EC.presence_of_element_located((MobileBy.ACCESSIBILITY_ID, "Search Wikipedia"))
    )
    search_element.click()

    search_input = WebDriverWait(context.browser, 30).until(
        EC.element_to_be_clickable((MobileBy.ID, "org.wikipedia.alpha:id/search_src_text"))
    )
    search_input.send_keys(keyword)
    time.sleep(5)


@then(u'Search results should appear')
def step_impl(context):
    elems = context.browser.find_elements_by_class_name("android.widget.TextView")
    assert len(elems) > 0, "results not populated"

If you are using our Sample App, the sample test below will install the Sample App (WordPress App) on the device, navigate to the Login screen, enters the login email and check whether the email is registered on WordPress. If you are using your own app, modify the code as per your test cases.

# WordPress Feature
Feature:
    Scenario: Displayed Text should match Input Text
        Given I open the app and click on Text Button
        Then Type "hello@browserstack.com" and hit enter
        Then Verify displayed text matches input text
@given('I open the app and click on Text Button')
def step_impl(context):
    element = WebDriverWait(context.browser, 30).until(
        EC.presence_of_element_located((MobileBy.ACCESSIBILITY_ID, "Text Button"))
    )
    element.click()


@then(u'Type "{text}" and hit enter')
def step_impl(context, text):
    text_input = WebDriverWait(context.browser, 30).until(
        EC.element_to_be_clickable((MobileBy.ACCESSIBILITY_ID, "Text Input"))
    )
    text_input.send_keys(text+"\n")
    time.sleep(5)


@then(u'Verify displayed text matches input text')
def step_impl(context):
    text_output = WebDriverWait(context.browser, 30).until(
        EC.element_to_be_clickable((MobileBy.ACCESSIBILITY_ID, "Text Output"))
    )
    if text_output!=None and text_output.text=="hello@browserstack.com":
        assert True
    else:
        assert False

To actually run the test case, we need to integrate with BrowserStack as follows:

Integration with BrowserStack

Note: Running your Behave tests on BrowserStack requires a username and an access key.

Integration of Behave with BrowserStack is made possible by use of following module:

from appium import webdriver
from browserstack.local import Local
import os, json

CONFIG_FILE = os.environ['CONFIG_FILE'] if 'CONFIG_FILE' in os.environ else 'config/single.json'
TASK_ID = int(os.environ['TASK_ID']) if 'TASK_ID' in os.environ else 0

with open(CONFIG_FILE) as data_file:
    CONFIG = json.load(data_file)

bs_local = None

BROWSERSTACK_USERNAME = os.environ['BROWSERSTACK_USERNAME'] if 'BROWSERSTACK_USERNAME' in os.environ else CONFIG['user']
BROWSERSTACK_ACCESS_KEY = os.environ['BROWSERSTACK_ACCESS_KEY'] if 'BROWSERSTACK_ACCESS_KEY' in os.environ else CONFIG['key']

def start_local():
    """Code to start browserstack local before start of test."""
    global bs_local
    bs_local = Local()
    bs_local_args = { "key": BROWSERSTACK_ACCESS_KEY, "forcelocal": "true" }
    bs_local.start(**bs_local_args)

def stop_local():
    """Code to stop browserstack local after end of test."""
    global bs_local
    if bs_local is not None:
        bs_local.stop()


def before_feature(context, feature):
    desired_capabilities = CONFIG['environments'][TASK_ID]

    for key in CONFIG["capabilities"]:
        if key not in desired_capabilities:
            desired_capabilities[key] = CONFIG["capabilities"][key]

    if 'BROWSERSTACK_APP_ID' in os.environ:
        desired_capabilities['app'] = os.environ['BROWSERSTACK_APP_ID']

    if "browserstack.local" in desired_capabilities and desired_capabilities["browserstack.local"]:
        start_local()

    context.browser = webdriver.Remote(
        desired_capabilities=desired_capabilities,
        command_executor="https://%s:%s@hub-cloud.browserstack.com/wd/hub" % (BROWSERSTACK_USERNAME, BROWSERSTACK_ACCESS_KEY)
    )

def after_feature(context, feature):
    context.browser.quit()
    stop_local()

The module reads from config file where you need to put the BrowserStack Hub URL and credentials. If the BROWSERSTACK_USERNAME and BROWSERSTACK_ACCESS_KEY are set in Environment variables, then that will take a preference. Also, update the app_url(bs://….) obtained after uploading the App to the BrowserStack cloud in Step 2.

{
  "user": "YOUR_USERNAME",
  "key": "YOUR_ACCESS_KEY",

  "capabilities": {
    "build": "behave-browserstack",
    "name": "single_test",
    "browserstack.debug": true,
    "app": "your_app_url"
  },

  "environments": [{
    "device": "Google Pixel"
  }]
}
{
  "user": "YOUR_USERNAME",
  "key": "YOUR_ACCESS_KEY",

  "capabilities": {
    "build": "behave-browserstack",
    "name": "single_test",
    "browserstack.debug": true,
    "app": "your_app_url"
  },

  "environments": [{
    "device": "iPhone 7"
  }]
}

Run your test on BrowserStack using following command:

# Run using paver
paver run single
Note: Refer to our GitHub repository for a complete example: BrowserStack - Behave

4. Viewing test results

You can access results of your test sessions on the App Automate dashboard as well as using our REST API. You can drill down into the details of a specific test session to view its execution details and debugging information such as video recording, network logs and device logs.