Edition 50

Special Capabilities for Speeding up Android Test Initialization

Happy start of 2019! This is another post from Appium contributor Jonah Stiennon. In the past, I've labeled his contributions to Appium Pro "guest posts", but as of now, Jonah has officially joined Cloud Grey as a partner! More to come about Jonah later, but meanwhile get ready to see more of him in this newsletter, on Appium's GitHub, and around the world consulting with you all.

Thanks to Appium contributor @AnnaWyrwal, there are two new desired capabilities available in the latest Appium beta release (see our earlier post on how to install beta versions of Appium). Under the right circumstances these can improve the time it takes to start an Android session.

skipDeviceInitialization

Available for all Android platforms, the skipDeviceInitialization desired capability can be passed with the boolean value true to skip installing the io.appium.settings app on the device. This special app is installed by the Appium Android Driver at the beginning of each test and is used to manage specific settings on the device, such as:

  • wifi/data settings
  • disabling animation
  • setting a locale
  • IME settings

Without the io.appium.settings app, the Appium Android driver cannot automate these functions, but if the device previously had this app installed by Appium, it doesn't need to install it again. If you know that your device is already in the proper state then you can set skipDeviceInitialization to true and skip the time it takes to reinstall it.

Appium already checks if the settings app is already installed on the device, but with this capability enabled it even skips the check to see if the app is installed.

This is most useful for tests which follow a previous successful test, or tests being run on the same emulators or devices over and over.

skipServerInstallation

The skipServerInstallation desired capability only applies when using the UiAutomator2 automation method. The way the UIAutomator2 driver works, it installs a special server onto the device, which listens to test commands from Appium and executes them.

By default, Appium installs this server onto the device at the beginning of every test session. If the value of skipServerInstallation is set to true, you can skip the time it takes to install this server.

Of course, without the server on the device Appium can't automate it, but if you know that the server was installed during a previous test run you can safely skip this step.

A warning: make sure to disable this capability if you have updated the version of Appium you are using, because you want it to install the latest version of the UIAutomator2 server.

This capability is also most useful for tests which follow a previous successful test, or tests being run on the same emulators or devices over and over.

Using appPackage and appActivity to launch existing apps

Another major time-saver when it comes to Android tests is using the appPackage and appActivity desired capabilities instead of the app capability.

We need to tell Appium which app to test. Usually we use the app capability, which can be a path to a .apk, .apks, or .zip file stored on your computer's filesystem or stored on a public website. If the app under test is known to already be installed on the device (most likely from a previous test run), the app package name and main activity can be passed instead (using appPackage and appActivity desired capabilities). Skipping the time to download a large file or install it on the Android operating system leads to big savings.

As with the previously discussed capabilities, make sure that you do install the app again if you are testing a newer version. Nothing is more frustrating than accidentally running tests on an older version of your app!

Honorary Mention: ignoreUnimportantViews

The ignoreUnimportantViews desired capability is not new, and is outside the scope of this post, but it deserves to be mentioned as another way to potentially speed up Android automation tests, especially if your tests focus on finding many elements using XPath locators. Set this to true to speed up Appium's ability to find elements in Android apps. (To learn more about this capability and other capabilities used for speeding up test execution, check out Part 6 of the series on making your Appium tests fast and reliable).

Below is an example of the skipDeviceInitialization, skipServerInstallation, and appPackage desired capabilities being used to speed up an Android test. The first test runs without these capabilities in order to make sure that the io.appium.settings app and the UiAutomator2-server are installed. The second test runs without bothering to check or install these dependencies or the app under test on the device. By my not-so-rigorous analysis, skipDeviceInitialization and skipServerInstallation saved about 1 second per test and using appPackage saved ten seconds per test (mostly because the example code downloads an app from the internet).

import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.IOException;
import java.net.URL;

import io.appium.java_client.AppiumDriver;

public class Edition049_Faster_Android_Capabilities {

    private String APP = "https://github.com/cloudgrey-io/the-app/releases/download/v1.8.0/TheApp-v1.8.0.apk";

    private AppiumDriver driver;
    private WebDriverWait wait;

    @Test
    public void testInstallingDependencies() throws IOException {
        DesiredCapabilities caps = new DesiredCapabilities();

        caps.setCapability("platformName", "Android");
        caps.setCapability("deviceName", "Android Emulator");
        caps.setCapability("automationName", "UiAutomator2");
        caps.setCapability("app", APP);

        driver = new AppiumDriver(new URL("http://localhost:4723/wd/hub"), caps);
        wait = new WebDriverWait(driver, 10);

        // Test code goes here

        driver.quit();
    }

    @Test
    public void testSkippingInstallOfDependencies() throws IOException {
        DesiredCapabilities caps = new DesiredCapabilities();

        caps.setCapability("platformName", "Android");
        caps.setCapability("deviceName", "Android Emulator");
        caps.setCapability("automationName", "UiAutomator2");

        // App is already installed on device, so can be launched by Package name and Activity
        caps.setCapability("appPackage", "io.cloudgrey.the_app");
        caps.setCapability("appActivity", "io.cloudgrey.the_app.MainActivity");

        // Skip the installation of io.appium.settings app and the UIAutomator 2 server.
        caps.setCapability("skipDeviceInitialization", true);
        caps.setCapability("skipServerInstallation", true);

        driver = new AppiumDriver(new URL("http://localhost:4723/wd/hub"), caps);
        wait = new WebDriverWait(driver, 10);

        // Test code goes here

        driver.quit();
    }
}