TECH.insight

Automated mobile app functional testing with Appium

Monday 16 March 2015

How do we ensure we deliver quality apps to the consumer?

With the use of mobile devices on the rise, there are mobile apps for almost everything. As developers, how do we ensure we deliver quality apps to the consumer? By extensive testing, of course. However, in this world of ever-changing buzzwords – agile, scrum, Continuous Integration, and Continuous Delivery – how does testing keep up with development?

Automated testing has long been the solution for high-volume and rapid-paced testing. But not until recent years was it possible to easily automate the testing of mobile apps on actual devices using open source, cost-effective means.

Appium is one such testing tool. In the last few years, it has quickly grown in popularity and stability as an open source, cross-platform test automation framework for native, hybrid and mobile web apps on iOS and Android. Appium uses the WebDriver JSON protocol to standardise the automation API across the two platforms and three app types.

In this article we will configure our computer and mobile devices for automation, configure Appium, and automate a basic smoke test.

Prepare the computer

To automate testing of a mobile device, you will need a computer capable of building and debugging iOS and Android devices. Since iOS development is only supported on Mac OS X, this article will assume a Mac is being used. You will need the following tools:

Prepare the device

On iOS, enable Web Inspector by navigating to Settings > Safari > Advanced and switching on the Web Inspector feature.

On Android, enable USB debugging by navigating to Settings > Developer options and selecting USB debugging. If the Developer options menu option is hidden, go to Settings > About phone and tap Build number seven times to reveal the option.

Prepare your app

Unlike other mobile automation frameworks, Appium does not require you to root your device or add any libraries or frameworks to your app source code.

On iOS, code sign and provision the app to run on a device using a development certificate – a standard requirement for developing iOS apps. The app should be stored in .app or .ipa format.

On Android, the app will need to be compiled and packaged into an .apk format.

For the purposes of this article, I’m going to assume we want to test the WordPress mobile apps, available across both iOS and Android. Prepare the WordPress Android app by building the debug version. Prepare the iOS app by archiving and exporting your app as an .ipa provisioned for a device.

Using Appium

Appium comes in two forms: a Node.js app that can be run from the command line, and a desktop app for OS X and Windows. The first is far more advanced, so let’s focus on the second.

Download, install and run the app from appium.io.

Across the top-left of the Appium window are buttons for settings. From left to right they are: Android settings, iOS settings, General settings, Developer settings and Robot settings. Yes, there is a real robot. Across the top-right are Inspector, Doctor and Launch buttons.

The Appium Window
The Appium window

Quick start

The Appium app can run in only one mode at a time: either Android or iOS, selected using the radio buttons below the respective settings button. Let’s take a look at each one individually.

Android mode

The Android settings look like the image below. Replace the app details and device name with your own Android device id.

Android settings
Android settings

iOS mode

The iOS settings look like the image below. Replace the app info and device UDID with your own.

iOS settings
iOS settings

Finding elements with the Inspector

Click Launch, then click the magnifying glass to start the Inspector. If all goes well, you should see the screen as shown below. Click on any element to see its details and to retrieve values you can use to locate the element in your test.

Appium inspector
Appium inspector

Here is an example of using an id to get the username field. In the Inspector we can use the Locator in the lower left to find elements, and then Touch or Text to interact with them.

If your app is a hybrid, the WebView will be listed under Context (be sure to run the ios_webkit_debug_proxy if you are using iOS). Next, we will use what we discover here to write the test in actual code.

Appium inspector search
Appium inspector search
Appium inspector inputting text
Appium inspector inputting text

Writing tests

Write some tests, or start with the sample code I’ve written here. The Selenium API is used to script tests – use any language or framework you choose. The code below shows what it looks like written in Java.

Documentation on other bindings can be found on Appium’s GitHub page. Almost every common language is supported.

Use the WebDriver DesiredCapabilities object to define the automationName, platformName, platformVersion, deviceName and app to match your Appium settings and Selenium will do the rest.

@Test
public void iCanSeeTheLoginErrorMessage() {

    // Define capabilities
    DesiredCapabilities capabilities = new DesiredCapabilities();
    capabilities.setCapability("automationName", "appium"); capabilities.setCapability("platformName", "Android");
    capabilities.setCapability("platformVersion", "4.4");
    capabilities.setCapability("deviceName", "123456789");
    capabilities.setCapability("app", "org.wordpress.android");

    // Define Selenium Grid URL
    URL seleniumGridUrl = null;
    try {
        seleniumGridUrl = new URL("http://0.0.0.0:4723/wd/hub");
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }

    // Start up an AppiumDriver session
    AppiumDriver ad = new AndroidDriver(seleniumGridUrl, capabilities);
    ad.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

    // Perform the test steps
    ad.findElement(By.id("org.wordpress.android:id/nux_username")).sendKeys("myusername@email.com");
    ad.findElement(By.id("org.wordpress.android:id/nux_password")).sendKeys("password123");
    ad.findElement(By.id("org.wordpress.android:id/nux_sign_in_button")).click();
    Assert.assertEquals(
        ad.findElement(By.id("org.wordpress.android:id/nux_dialog_title")).getText(),
        "We can't log you in");

    // Close the WebDriver session
    ad.quit();
}

The pros and the cons

For those who like to avoid compiling in third-party libraries or frameworks for testing, Appium is the perfect solution. It uses first-party automation instrumentation and does not require modifications to the source code. The combination of WebDriver and first-party instrumentation handles hybrid apps seamlessly.

While it’s fairly easy to build a debuggable Android app, it’s slightly more complex on the iOS side with the code signing and provisioning involved. This requires an iOS developer account and some developer chops to get the app signed. Once you get past those hurdles, the rest is the same as in the example above.

Scaling tests

Out of the box Appium supports the Selenium Grid architecture, meaning several Appium sessions with devices attached can be connected to a Selenium Grid. The tests would be queued and distributed to each connected device accordingly. The caveat here is that Xcode limits you to one iOS device debug session at a time, but you can get around this by running several virtual machines.

There are several companies that do just that: AppThwack and Appurify offer Appium-compatible device clouds. You can connect to their services via the Selenium Grid architecture, call up a device and run the tests – just as if the device were in front of you.

About The Author

An Doan is an 9th year “Dark Developer” specializing in writing code that breaks other code, he develops test automation by day, speaks and organizes automation meet-ups by night. He is highly versed in test automation frameworks and quality processes. As co-founder, and idea incubator of the Portland Selenium and Test Automation Users Group he helps the community share and develop creative ideas in the realm of testing and test automation.

@doan_an