Appium Tip #2: Using Python to Upload and Configure Your Apps and Tests

Everything About Appium Test Automation

This is the second blog of our 37 Things You Should Know About Appium blog series, and this time we’ll continue with some basic things around using Python with Appium. For starters, we’ll take a look at basic examples of how to use Python and write few lines of code to get your applications automatically uploaded for Testdroid Cloud to be executed on real Android and/or iOS devices.


If you followed through the first blog where we walked through the basic setup, installation of Python, and some other things, you can continue with the basic code example. If you don’t have Python properly installed or you need to check whether everything is ready to go forward, get our free Appium beginner’s guide to verify your setup and learn how to set up other languages.

Python is a worthwhile script language choice for those who want to get down to business quick and simple. The syntax is really easy to learn and implement and there isn’t typically a huge cluster of different files required. Usually when I want to test some Appium feature, which I haven’t touched before, I turn to python to check it out.

Creating and Running an Upload Script

First of all, you should have an account in Testdroid Cloud to get your tests running. You can create account here for free and use it as much as you want, regardless of what service level (FREE or PAID) you’ll end up using.

Before the actual testing can happen, you need to upload you mobile application to the cloud. The app can be in form of APK or IPA – and to get you an effective start, we’ll create a brief upload script here. The upload script example is also available at Github. For IPA files, please also make sure they’re properly built for use in Testdroid Cloud.

import requests
import base64

username = 'USERNAME'
password = 'PASSWORD'
upload_url = ''
myfile = '../../../apps/builds/Testdroid.apk'

def build_headers():
  return { 'Authorization' : 'Basic %s' % base64.b64encode(username+":"+password) }

files = {'file': ('Testdroid.apk', open(myfile, 'rb'), 'application/octet-stream')}
r =, files=files, headers=build_headers())
print r.text

Configure your username, password and myfile attributes with your Testdroid Cloud login credentials, and file path for your application (this can be APK or IPA).

Now, you can run the upload script using the following command:

$ python

As an output you’ll get something like this:

{"status":0,"sessionId":"99becd25-3183-4c7f-998e-84ef307de7a5","value":{"message":"uploads successful","uploadCount":1,"rejectCount":0,"expiresIn":1800,"uploads":{"file":"99becd25-3183-4c7f-998e-84ef307de7a5/test.apk"},"rejects":{}}}

From this response message you need to store the application’s ID and file name in Testdroid Cloud. The above example is '99becd25-3183-4c7f-998e-84ef307de7a5/test.apk'.

Creating and Running a Test Script

Generic Settings

There are some common settings that you need to set in all scripts regardless of the app type that you are testing. Each testdroid_*.py file needs to be updated with the appropriate values. For this example, here are all the values that you need to edit:

screenshotDir – where should screenshots be stored on your local drive
testdroid_username – your email that you registered with to Testdroid Cloud
testdroid_password – your Testdroid Cloud password
testdroid_project – the name of the project you want to use in Testdroid Cloud. Each project must have a unique name, which can also be modified later. The project will be automatically created, if it doesn’t already exist in cloud.
testdroid_testrun – name of this test run. Test run names can also be modified afterwards and they don’t have to be unique.
testdroid_app – the location of the app you uploaded to cloud. Eg. if you uploaded your app using the script this would look like ’99becd25-3183-4c7f-998e-84ef307de7a5/test.apk’. Alternative way to this is uploading the app through the cloud portal and then use the value ‘latest’ instead of an id path.

Native Android Specific Settings

You can use our template file as an example: from Github.

In order to configure this script for your testing needs and for your own app, you can edit two additional capabilities as follows:

appPackage – Java package of the Android app you want to run
appActivity – Activity name for the Android activity you want to launch from your package. Typically this is the main activity.

Native iOS Specific Settings

You can use our template file as an example: from Github.

NOTE! In addition to other configurations and desired capabilities, Appium requires a bundle id to be included in the test script:

bundleId – this is your application’s unique name. For example, it can be used in your Python test script as follows:

'bundleId': 'com.bitbar.testdroid.BitbarIOSSample'

An Example Template for Desired Capabilities and Setup

You can find all the template scripts from our Github repository. There are examples for Android, iOS, Safari, Chrome, and additionally Android hybrid for hybrid apps.

Okay, let’s look at a concrete Python test script example then and what goes in the code:

Imported libraries, bundles and other libraries/dependencies:

import os
import sys
import time
import unittest
from time import sleep
from appium import webdriver
from device_finder import DeviceFinder
from selenium.common.exceptions import WebDriverException

Next, let’s create a class with the device, login and configuration specific desired capabilities. For example:

class AndroidTest(unittest.TestCase):
    def setUp(self):
    self.screenshotDir = os.environ.get('TESTDROID_SCREENSHOTS') or "/absolute/path/directory"
    testdroid_url = os.environ.get('TESTDROID_URL') or ""
    testdroid_username = os.environ.get('TESTDROID_USERNAME') or ""
    testdroid_password = os.environ.get('TESTDROID_PASSWORD') or "password"
    appium_url = os.environ.get('TESTDROID_APPIUM_URL') or ''

To choose a device from Testdroid Cloud, you can search for the desired model from our Device Groups page. Once you found the model you want to use, simply copy the full name of the device to testdroid_device variable.

You can also use the DeviceFinder class to automatically find an available freemium device for your test run at Testdroid Cloud:

deviceFinder = None
testdroid_device = os.environ.get('TESTDROID_DEVICE') 

deviceFinder = DeviceFinder(username=testdroid_username, password=testdroid_password, url=testdroid_url)
if testdroid_device == "":
  # Loop will not exit until free device is found
  while testdroid_device == "":
        testdroid_device = deviceFinder.available_free_android_device()

Then, to choose correct automation backend for the server, you need to fetch the API level of the device which will be used for a test run:

apiLevel = deviceFinder.device_API_level(testdroid_device)

Finally, let’s take a look at desired capabilities configuration with your Python script.

desired_capabilities_cloud = {}
desired_capabilities_cloud['testdroid_username'] = testdroid_username
desired_capabilities_cloud['testdroid_password'] = testdroid_password
if apiLevel > 17:
  desired_capabilities_cloud['testdroid_target'] = 'Android'
  desired_capabilities_cloud['testdroid_target'] = 'Selendroid'

desired_capabilities_cloud['testdroid_project'] = os.environ.get('TESTDROID_PROJECT') # eg.'Demo'
desired_capabilities_cloud['testdroid_testrun'] = os.environ.get('TESTDROID_TESTRUN') # eg.'MyTest'
desired_capabilities_cloud['testdroid_device'] = testdroid_device
desired_capabilities_cloud['testdroid_app'] = 'sample/BitbarSampleApp.apk'
desired_capabilities_cloud['platformName'] = 'Android'
desired_capabilities_cloud['deviceName'] = 'Android Phone'
desired_capabilities_cloud['appPackage'] = 'com.bitbar.testdroid'
desired_capabilities_cloud['appActivity'] = '.BitbarSampleApplicationActivity'

One more thing! Let’s initiate and set up WebDriver:

desired_caps = desired_capabilities_cloud;
self.driver = webdriver.Remote(appium_url, desired_caps)


You can set Environment Variables to store all the desired capabilities that won’t be changing often. This logic is already included in the sample scripts so all you need to do is set the variables! For example, to set your Testdroid Cloud username, simply apply to your environment and the script will then find it with the os.environ.get() function. If the variable doesn’t exist, the script will move on to the next declaration after the ‘or’ key word.

Playing around with the Android appPackage and appActivity values may be useful when creating tests to automate specific activity screens of your app. There is also a command to launch another app while one is already being tested! This functionality is available for Android only though.

Happy Appium Testing (and weekend)! We’ll be continuing with a new topic on Monday!

The Beginner’s Guide of Using Appium for Mobile App Testing

Learn all the basics about Appium, how to set it up and how to use it for mobile app testing.


  • Anda Cristea

    Do you have the sample code for Java?