ATS : Automated testing of Android or iOS application

Introduction

This page shows how to use the ATS UI Engine in order to automate the UI testing of native, hybrid and mobile web applications. This includes applications in emulator or real mobile device.

NO device rooting, NO patching, NO instrumentation(recompiling with additional modules/libraries) of the tested application is needed!
The tests runs against the same application provided to the clients.

The current implementation uses Appium framework, but if this get changed in the future, the UI Engine needs to make the change transparent to the test cases.

There are some preparation/configuration steps in order to run tests. For more details see Configuration section.



Quick example

Here we will take a look at a simple example to see how mobile engine tests look like

// 1. initialize the driver (device connector)
MobileDriver mobileDriver = UiDriver.getMobileDriver( MobileDriver.DEVICE_ANDROID_EMULATOR, "4.4", null, "localhost" );
mobileDriver.setAndroidHome( "D:\\android\\android-sdk_r24.0.2\\" ); // if not already set as an Environment Variable (ANDROID_HOME)

// 2. start the driver (starts the device emulator if not already started and load the tested application)
mobileDriver.start( "D:\\mobile_apps\\android\\SecureTransportMobile.apk" );

// 3. get the engine to work with
MobileEngine mobileEngine = mobileDriver.getMobileEngine();

// 4. specify the file describing the UI components we want to work with
mobileEngine.loadMapFile( "MyUiComponents.map", "login" );

// 5. work with some UI components
mobileEngine.getTextBox( "usernameTB" ).setValue( "admin" );
mobileEngine.getTextBox( "passwordTB" ).setValue( "pass" );
mobileEngine.getButton( "loginB" ).click(); // "tap" on the button

// 6. stop the driver ( close the tested application )
mobileDriver.stop();

This example basically does the following:

  1. Initialize the device connection:
    - we specify we will be working with Android emulator. Other possibilities are Android device, iPhone/iPad simulator or a specific iPhone/iPad device (iPad 2, ...)
    - for Android a path to the ANDROID_HOME is needed to be specified
  2. Start the driver - starts the device emulator/simulator if not already started and load the tested application
  3. Get a reference to the later used engine, in this example this is an MobileEngine as we will be testing a mobile application.
  4. Specify the file describing the UI components we want to work with
    - in this example we suppose we have a map file which defines the UI components of interest. We also have dedicated a section in that file called "login" which contains the components at the login page of our application.
  5. Work with some UI components. In our case we:
    - set the value of a Text Box with our user name
    - set the value of a Text Box with our password
    - click/tap a login Button
  6. Stop the driver - close the tested application



Configuration

Setup environment

  • Android
    1. Install Android SDK
      > /opt/android/android-sdk_r24.0.2/tools/android &
    2. Setup environment variables
      > export PATH=/opt/android/android-sdk_r24.0.2/platform-tools/:$PATH
      > export ANDROID_HOME=/opt/android/android-sdk_r24.0.2/
    3. Create and start AVD (Android Virtual Device)
      > /opt/android/android-sdk_r24.0.2/tools/android avd &
  • iOS
    1. Install Xcode
    2. (Optional) Open and do some settings to the iOS Simulator (for example iCloud server)
      > open /Applications/Xcode.app/Contents/Developer/Applications/iOS\ Simulator.app

Install and start Appium Server

  • Windows
    Use Appium installer (Appium-windows-nnnnn.zip) from here
  • Mac OS X
    Use Appium installer (Appium-mac-NNN.dmg) from here
  • Linux
    1. Install node.js and npm (its packet manager)
    2. Install Appium server
      > npm install -g appium
      > npm install wd
    3. Start Appium server
      > appium --session-override

Configure Appium Server

An important option that should be used in most of the cases is --session-override, which allows next test executions to use create a new session and override the existing one. Sometimes the connection could drop or a test could miss session closing due to an error and without session overriding the next test executions would fail until the session expires and a new one could be successfully created.

Detailed information about the Appium Server start options/flags can be found here.

UiEngine Configuration

Using the UiEngineConfigurator class you can do some changes to the UI Engine behavior.

For example, the following code will change how long time to wait for an element to be found

// wait for up to 5 seconds
UiEngineConfigurator.getInstance().setElementStateChangeDelay( 5000 );



Mobile Driver initialization

Mobile driver initialization happens through the UiDriver.getMobileDriver(...) method, where accepted arguments are:

  • deviceName - the kind of mobile device or emulator to use. You can use one of MobileDriver driver type constants. For example: Android Emulator, iPhone Simulator, iPad Simulator, iPhone Retina 4-inch, Galaxy S4, ... On iOS, this should be one of the valid devices returned by instruments with "instruments -s devices"
  • platformVersion - mobile OS version. For example: 8.1, 4.4 ... For Android it could be skipped (null)
  • udid - unique device identifier of the connected physical device or null for emulator/simulator usage
  • host - the host address of the Appium server. null may be passed if you want to work with localhost emulator
  • port - the port number of the Appium server or null to use the default Appium server port 4723

Examples:

For Android
MobileDriver driver = UiDriver.getMobileDriver( MobileDriver.DEVICE_ANDROID_EMULATOR, null, null, "127.0.0.1" );
driver.setAndroidHome( "D:\\android\\android-sdk_r24.0.2\\" ); // if not already set as an Environment Variable (ANDROID_HOME)
For iOS
MobileDriver driver = UiDriver.getMobileDriver( MobileDriver.DEVICE_IPAD_SIMULATOR, "8.1", null, "10.11.12.13" );
// or
MobileDriver driver = UiDriver.getMobileDriver( "iPad 2", "8.1", "1ae203187fc012g", "10.11.12.13" );

Supported UI elements


Following is the current list with all supported UI elements. They work both for Android and iOS platform.

You can see the java classes per UI element, the list of actions you can run on each UI element and the list of attributes the needed to find the UI element.

Button

A button

class

instantiation

searched by

MobileButton

mobileEngine.getButton()

1. id



2. name



3. text



4. partialText



5. xpath

methods

description

click

tap it

clickIfExists

tap it if exists specifying a waiting timeout

scrollTo

scroll to the element

getTextContent

get its text content

getAttributeValue

get element attribute value

Text Box

A single line text box which value can be changed

class

instantiation

searched by

MobileTextBox

mobileEngine.getTextBox()

1. id



2. name



3. text



4. partialText



5. xpath

methods

description

getValue

get its value

setValue

set its value

verifyValue

verify its value is as specified

verifyNotValue

verify its value is not as specified

click

tap it

clickIfExists

tap it if exists specifying a waiting timeout

scrollTo

scroll to the element

getTextContent

get its text content

getAttributeValue

get element attribute value

Check Box

A check box

class

instantiation

searched by

MobileCheckBox

mobileEngine.getCheckBox()

1. id



2. name



3. text



4. partialText



5. xpath

methods

description

check

check it

unCheck

un-check it

isChecked

tell if it is checked

verifyChecked

verify it is checked

verifyNotChecked

verify it is not checked

click

tap it

clickIfExists

tap it if exists specifying a waiting timeout

scrollTo

scroll to the element

getTextContent

get its text content

getAttributeValue

get element attribute value

A link

class

instantiation

searched by


MobileLink

mobileEngine.getLink()

1. id



2. name



3. text



4. partialText



5. xpath

methods

description

click

tap it

clickIfExists

tap it if exists specifying a waiting timeout

scrollTo

scroll to the element

getTextContent

get its text content

getAttributeValue

get element attribute value

Generic element

Any element. This is generic case to work with any element and also container ones like views and div/span elements in HTML.

class

instantiation

searched by

MobileElement

mobileEngine.getElement()

1. id



2. name



3. text



4. partialText



5. xpath

methods

description

click

tap it

clickIfExists

tap it if exists specifying a waiting timeout

scrollTo

scroll to the element

getTextContent

get its text content

getAttributeValue

get element attribute value

Popups - Alerts, Prompts and Confirms

Elements in like Alert,Prompt are found the same way as other UI elements.



Running against real devices

Android

  1. Connect device to computer via USB.
  2. Make sure device and computer are connected to the same WiFi network.
  3. Run this command to restart adb in TCP mode and setups connections to the adb daemon on the device on port 5555 (http://developer.android.com/tools/help/adb.html):

    adb tcpip 5555
    
  4. Disconnect device from the USB cable
  5. Get IP address of your phone ("Settings" -> Wifi -> "Your connected network" -> "Your IP address")
  6. Run this command to connect adb to your device over Wifi using its IP address:

    adb connect <IP address>
    
  7. Verify, that adb works remotely:

    adb devices
    
  8. Run the tests (now over WiFi)

WebView issue on Android 4.4 or later

On Android 4.4 (KitKat/API 19) or later, in order to debug WebViews on real devices you have to enable it explicitly in the application code.
To enable WebView debugging, call the static method setWebContentsDebuggingEnabled on the WebView class (source).

Enable WebView debugging only when debuggable is true (Developer options is ON)
import android.webkit.WebView;
import android.content.pm.ApplicationInfo;
import android.os.Build;
...
public void onCreate(Bundle savedInstanceState) {
    ...
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        if (0 != (getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE)) {
            WebView.setWebContentsDebuggingEnabled(true); 
        }
    }
    ...
}



Troubleshooting

Currently Appium shows the original/actual error in its Console only (we hope it will be fixed soon and these errors will be passed to the Appium Java client and we will have more accurate exception messages), so if you doesn't understand the reason of the failure check the Appium console for the last error message (search for text like: "Original error: ...").

Error: "We already have a chromedriver instance running"

There are more than one "chromedriver" instances running. To fix that, kill all chromedriver instances and start Appium server again

Error: "'java -version' failed. Error: spawn ENOENT"

This error appears on the Appium console even when the 'java -version' works and the PATH variable looks fine, but the problem is there. %PATH% must also contain the windows system directories (i.e. %SystemRoot%\system32;%SystemRoot%), because behind the scenes Appium uses something in those directories when launching 'java -version' (source: https://github.com/appium/appium/issues/4229)



Back to parent page

Go to Table of Contents