Running parallel tests with Appium

Pre-requisites

First, you will need to enable and connect your devices to adb. To do so, please refer to Accessing a virtual device from ADB.

Start appium server

Since Appium 1.7, it’s easy to do parallel testing using only one appium server. Before that, we had to start N appium servers in order to test N devices in parallel.

So let’s start an Appium server, simply using the basic command:

appium

Write your tests script in Python

We will use Python throughout this tutorial but you can use a different language if you prefer.

We’ve chosen to use Pytest as our test framework. It has several useful plugins like:

  • xdist: for running tests in parallel.
  • rerunfailures: for rerunning failed tests an arbitrary number of times to reduce build failures due to flaky tests

Here is a simple python script, please replace [instanceX_ip] values by the IPs of your instances:

# test_example.py
# -*- coding: utf-8 -*-
import pytest
from appium import webdriver

@pytest.mark.parametrize("udid, systemPort", [
       ("[instance1_ip]:5555", "8201"),
       ("[instance2_ip]:5555", "8202"),
       ("[instance3_ip]:5555", "8203"),
       ]
)
def test_sum(udid, systemPort):

   capabilities = {
       'platformName': 'Android',
       'deviceName': 'Genymotion Cloud PaaS',
       'appPackage': 'com.android.calculator2',
       'appActivity': '.Calculator',
       'udid':udid,
       'systemPort': systemPort,
       'automationName': 'UiAutomator2',
       'noReset': True,
   }
   url = 'http://localhost:4723/wd/hub'
   driver = webdriver.Remote(url, capabilities)

   try:
       digit1_btn = driver.find_element_by_id("com.android.calculator2:id/digit_1")
       digit1_btn.click()

       add_btn = driver.find_element_by_id("com.android.calculator2:id/op_add")
       add_btn.click()

       digit2_btn = driver.find_element_by_id("com.android.calculator2:id/digit_2")
       digit2_btn.click()

       equal_btn = driver.find_element_by_id("com.android.calculator2:id/eq")
       equal_btn.click()

       sum_input = driver.find_element_by_id("com.android.calculator2:id/result").text
       assert sum_input == "3"

   finally:
       # teardown appium
driver.quit()

For convenience, we will call this python script test_example.py.

How to run Python tests in parallel

If we run the python script as follows:

pytest test_example.py

pytest will execute tests on one device at a time. However, in order to have results as soon as possible, we need to execute all the tests at the same time. To do that, we can take advantage of the pytest-xdist plugin and run the following command :

pytest -n 3 test_example.py
  • -n : number of worker processes you want to use. Here we start the suite with 3 processes.

How to run Python tests in parallel with Java

A Riddle application is used for testing. It runs 2 same tests on 2 devices. The application needs to be already installed on the device but you can change those 2 lines to capabilities.setCapability(MobileCapabilityType.APP, $PWD/Apps/appriddle.apk); where $PWD is the absolute path where your project is located.

Configuring devices used for testing is there. Replace the udid by the ADB serial number of the device.

Run the tests :

  1. Start the devices and connect it to your computer/CI server

  2. Start appium server

    appium
    
  3. Run project

    mvn test
    

To see an example of:

  • test sharding (splitting a set of tests and run each batch on several devices), please refer to the test_sharding branch
  • implementing retries to avoid flaky tests, please refer to the flaky_tests branch.