Skip to content

Just a few years ago, the process of mobile test automation was too immature and the entire mobile ecosystem wasn’t ready to adopt large scale test automation setups for mobile app testing. Furthermore, test automation wasn’t necessarily seen as possible to be done across devices, simultaneously, and in parallel mode. Nowadays, things are a whole lot different. Test automation, with frameworks like Appium, real devices, a variety of different hardware and using network connections and real back-ends intensify testing of Android and iOS apps.

This is the 21st blog in our Things Should Know About Appium – and we’ll go through a basic example of how to get Appium test started on available Android and/or iOS devices, just in seconds using device finder functionality.

appium-tip-21-thumbnail-with-text

One of the hurdles when it comes to setting up a large set of devices has been around the physical connection of devices to server machines and setting up everything with ADB or Xcode access. However, acquiring a device for Appium test is trivial and rapid nowadays using Bitbar device finder. In addition, there are no limitations on which programming language you need to use to define preferred steps for your tests. Download our free Appium ebook that covers the essentials of a proper Appium environment to successfully skip the queues of test execution.

API Key Authentication for Cross-Platform Appium Tests

The first thing to do is to use a path for API call to get a list of all devices. Based on Bitbar API document, you should use https://cloud.testdroid.com/api/v2/devices?limit= for initialization. A better and yet easier way to handle all connections between your local instance and Bitbar Testing is the API Key authentication instead of OAuth authentication.

class CrossPlatformDeviceFinder:
    url = None
    def __init__(self, url="https://cloud.testdroid.com", download_buffer_size=65536):
        self.cloud_url = url
        self.download_buffer_size = download_buffer_size
    def _build_headers(self, headers=None):
        hdrs = {}
        hdrs["Accept"] = "application/json"
        if headers != None:
            hdrs.update(headers)
        return hdrs
    def get_devices(self, limit=0):
        return self.get("devices?limit=%s" % (limit))
    def get(self, path=None, get_headers=None):
        url = "%s/api/v2/%s" % (self.cloud_url, path)
        headers=self._build_headers(get_headers)
        res =  requests.get(url, headers=self._build_headers(get_headers))
        if res.ok:
            return res.json()
        else:
            print "Could not retrieve any devices."
            sys.exit -1

The API key is a unique identifier for every user. It’s generated when signing up for the service and it can be changed at any time. In short, the Bitbar API key makes the entire the login procedure and communication faster as you are you are not required to use access token all the time. The API key also improves the security as you are not required to play with your credentials and expose those with your test scripts.

The API key is can be fetched from your Bitbar Testing profile (Profile -> My account -> API key):

Screen Shot 2015-08-27 at 11.05.51 AM

In order to reset API key (recommended every now and then), just click ‘Reset API key‘.

Select Devices for Tests in Desired Capabilities

Appium desired capabilities can be used to identify what devices will be used for a test run. In this example, it is just a simple table including all the device names. This kind of approach can be also used as a cross-platform device acquisition (e.g. listing both Android and iOS devices).

Here is a basic example of how to list devices in Python for these described scripts:

   AndroidDevices = [“Acer Iconia Tab 8”,
                     “HTC One M9”,
                     “Motorola Google Nexus 6”,
                     “Samsung Galaxy Note 5”,
                     “Samsung Galaxy Tab 4 10.1”,
                     “Sony Xperia Tablet Z”,
   ]
   ...
   for each device in AndroidDevices:
       testdroidDevice =  CrossPlatformDeviceFinder.getDevice(device)
       if testdroidDevice is not None:
          break
   ...

Acquiring Android Devices for Appium Test Run

In addition to prior pseudo code example, you can use more specific search parameters in your device acquisition. For example, you can combine the script below with your instigator script to acquire and access just specific device you want for your test run.

    def available_android_device(self, limit=0):
        print "Searching Available Android Devices..."
        for device in self.get_devices(limit)['data']:
            if device['locked'] == False and device['osType'] == "ANDROID"
               and device['softwareVersion']['apiLevel'] > 16:
                print "Found device '%s'" % device['displayName']
                print ""
                return str(device['displayName'])
        print "No available Android devices were found."
        print ""
        return ""

The API level matters in Android and even Appium uses different foundations for older versions of Android. For example, if your app must run on devices with API level below 17, Appium is using Selendroid as a basis and on newer API levels it will use uiautomator. Furthermore, you can use something as follows for checking the API level of any Android device:

    def device_API_level(self, deviceName):
        print "Searching for API level of device '%s'" % deviceName
        try:
            device = self.get(path="devices", get_headers={'search':deviceName})
            apiLevel = device['data'][0]['softwareVersion']['apiLevel']
            print "Found API level: %s" % apiLevel
            return apiLevel
        except Exception, e:
            print "Error: %s" % e
            return

Screen Shot 2016-01-19 at 1.28.56 PM

Acquiring iOS Devices for Appium Test Run

In iOS device acquisition, the OS version isn’t important. Instead, you should pre-define those devices in some table before calling the available_ios_device(). Here is one example how to use pre-defined devices for this search:

   iOSDevices = [“Apple iPad 3 A1416 8.2”,
                 "Apple iPad Air 2 A1566 8.4",
                 "Apple iPad Mini 3 A1599 9.0.2"
   ]
   ...
   for each device in iOSDevices:
       testdroidDevice =  CrossPlatformDeviceFinder.getDevice(device)
       if testdroidDevice is not None:
          break
   ...

In order to find available iOS devices you can use the following type of script to identify those and get the device up and running with your app and tests:

    def available_ios_device(self, limit=0):
        print "Searching Available iOS Device..."
        for device in self.get_devices(limit)['data']:
            if device['locked'] == False and device['osType'] == "IOS":
                print "Found device '%s'" % device['displayName']
                print ""
                return str(device['displayName'])
        print "No available devices were found."
        print ""
        return ""

Benefits of Cross-Platform Device Finder

Appium provides a great framework for test automation but parallel test execution hasn’t been too easy just by defining a group of devices where your app and test should do its heavy-lifting.

With these instructions and few examples, you should be able to build tests that 1) get started instantly (as script acquires those devices that are available at that very moment), 2) enable simultaneous/parallel/concurrent test runs (with instigator script where you define devices that you want to run on) and 3) provide you results from devices that you see important for your app.

Happy Appium Test Automation!

Ville-Veikko Helppi

Mobile Testing Expert