Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}
Refcard #239

Getting Started With Appium

Mobile App Automation Made Awesome

Written by

Dave Haeffner Author, Elemental Selenium

In this Refcard you will learn everything you need to know about getting started with this open-source tool, from installing the Appium server to running your first tests. Download this Refcard now to see why Appium is "Mobile App Automation Made Awesome."

Free PDF
DOWNLOAD
Brought to you by Sauce Labs
Section 1

What is Appium?

Appium is a free and open-source mobile automation framework used for native, hybrid, and mobile web apps. It works on iOS, Android, Mac, and Windows apps using the WebDriver protocol. WebDriver (the API to automate browsers, maintained by the Selenium project) is currently going through a W3C (World Wide Web Consortium) specification.

Section 2

Getting Started

In order to get up and running on your local machine, you need to download an Appium server and client bindings for your preferred programming language. There are Appium language bindings for multiple programming languages. The officially supported ones (in alphabetical order) are:

  • C# (.NET)

  • Java

  • JavaScript (Node.js)

  • PHP

  • Python

  • Ruby

NOTE: There are also some platform specific dependencies you'll need for testing on iOS and Android. For an up-to-date reference, be sure to check out the Appium documentation.

Appium Server

There are two approaches you can take for getting the Appium Server onto your machine. You can use the command-line server available through npm and install it with npm install -g appium.

Alternatively, you can use the Appium Desktop app, which is an open source app for Mac, Windows, and Linux which gives you the Appium server in a simple and flexible UI (along with some extra functionality). You can download and install the latest version here.

NOTE: If you have any questions about Appium Desktop be sure to check out its documentation.

After you have the server installed, be sure to run it (appium if using the command-line server, or launch the Appium Desktop app and click Start Server), then download and install the client bindings for your preferred programming language.

C# (With NuGet)

Use the following commands from the Package Manager Console window in Visual Studio to install the Appium C# bindings (which is an extension of the Selenium client bindings).

Install-Package Selenium.WebDriver
Install-Package Newtonsoft.Json
Install-Package Selenium.Support
Install-Package Castle.Core

NOTE: You will need to install Microsoft Visual Studio and NuGet to install these libraries and build your project. For more information on the Appium C# bindings checkout the API documentation.

Java (With Maven)

In your test project, add the following code to your pom.xml. Once that’s done you can either let your IDE (Integrated Development Environment) use Maven to import the dependencies or open a command-prompt, cd into the project directory, and run mvn clean test-compile.

<!-- https://mvnrepository.com/artifact/io.appium/java-client -->
<dependency>
    <groupId>io.appium</groupId>
    <artifactId>java-client</artifactId>
    <version>LATEST</version>
    <scope>test</scope>
</dependency>

NOTE: You will need to have the Java Development Kit (version 7+, or 8+) and Maven installed on your machine. For more information on the Appium Java bindings, check out the API documentation.

JavaScript (npm)

Type the following command into a command-prompt to install the JavaScript bindings for Appium:

npm install webdriverio
npm install wdio-appium-service --save-dev

NOTE: You will need to have Node.js and NPM installed on your machine. For more information about the Appium JavaScript client bindings, check out the API documentation.

PHP (With Composer)

Add "appium/appium-php": "dev-master" to the require section of your composer.json file, as well as the Appium PHP GitHub repository to the repositories section.

{
    "name": "username/my-php-project",
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/appium/php-client"
        }
    ],
    "require": {
        "appium/php-client": "dev-master"
    }
}

Then install the dependencies and run your tests.

composer install
vendor/phpunit/phpunit/phpunit <mytest.php>

NOTE: For more details on the PHP Appium Client bindings, be sure to check out the documentation.

Python

Type the following command to install the Python bindings for Selenium:

pip install Appium-Python-Client

NOTE: You will need to install Python, pip, and setuptools in order for this to work properly. For more information on the Appium Python bindings, check out the API documentation.

Ruby

Type the following command to install the Appium Ruby bindings:

gem install appium_lib

NOTE: You will need to install a current version of Ruby which comes with RubyGems. You can find instructions on the Ruby project website. For more information on the Appium Ruby bindings, check out the API documentation.

Platform Dependencies (iOS)

For testing on iOS, you'll need to install Xcode and the Xcode Command Line Tools Package. The Command Line Tools Package can be installed with the xcode-select --install command in your terminal once Xcode has been installed.

You'll also need to authorize Appium to use the iOS Simulator, which you can do with the following commands:

npm install -g authorize-ios
sudo authorize-ios

If you're using Xcode 8 & iOS 10 (or newer), you'll also need to install the following libraries:

brew install carthage
brew install libimobiledevice
npm install -g ios-deploy

NOTE: For additional information on system setup requirements (since your needs might be different), be sure to check out the Appium documentation.

Platform Dependencies (Android)

For testing on Android, you'll need to download the Android Command Line Tools, unzip them to a known location, and specify that location in an ANDROID_HOME environment variable and your system path.

export ANDROID_HOME="$HOME/android"
export PATH="$ANDROID_HOME/tools:$PATH"
export PATH="$ANDROID_HOME/platform-tools:$PATH"

Once done, run android sdk from the command-line to select and install the SDK version that you'd like to use (e.g., Android SDK Build Tools 23.0.3). Then run android avd from the command-line to create an emulator for your tests to use (for the examples that follow we'll be using an avd called example).

NOTE: For additional information on system setup requirements (since your needs might be different), be sure to check out the Appium documentation.

Verify Your Machine Is Setup

To verify that all of Appium’s dependencies are met, you can use appium-doctor.

To install it, use npm install -g appium-doctor. Then run it with appium-doctor. You can supply it with --ios or --android flags to verify that all of the dependencies are set up correctly for that particular platform.

NOTE: The remaining examples will be shown using Ruby.

Sample Apps

Don't have a test app? Don't sweat it. There are pre-compiled test apps available to kick the tires with. You can grab the iOS app here and the Android app here.

Just make sure to put your test app in a known location, because you'll need to reference the path to it next.

App Configuration

When it comes to configuring your app to run on Appium there are a lot of similarities to Selenium -- namely the use of Capabilities (e.g., "caps" for short). You can specify the necessary configurations of your app through caps by storing them in a file called appium.txt.

Here's what appium.txt looks like for the iOS test app to run in an iPhone simulator:

[caps]
platformName = "iOS"
deviceName = "iPhone Simulator"
app = "/path/to/UICatalog.app"
automationName = "XCUITest"

[appium_lib]
sauce_username = false
sauce_access_key = false

And here's what appium.txt looks like for Android on a local emulator:

[caps]
platformName = "ANDROID"
deviceName = "Android 6.0"
app = "/path/to/api.apk"
avd = "example"

[appium_lib]
sauce_username = false
sauce_access_key = false

For Android, note the use of avd. The "example" value is for the Android Virtual Device that was mentioned previously in the Platform Dependencies (Android) section. This is necessary for Appium to auto-launch the emulator and connect to it. This type of configuration is not necessary for iOS.

NOTE: You can see a full list of available caps here.

Go ahead and create an appium.txt file with the caps for your app.

Section 3

Interrogating Your App

Writing automated scripts to drive an app in Appium is very similar to how it's done in Selenium. You first need to choose a locator which finds an element that you can then perform an action against.

In Appium, there are two approaches to interrogating an app to find the best locators to work with — through the command-line with Ruby's irb (a.k.a. interactive Ruby) or through Appium Desktop. Here are some examples of how to use each of these approaches to decompose and understand your app:

Using the Command-Line

Initial Setup

  1. Confirm you have the Appium Ruby client bindings installed (e.g., gem install appium_lib)

  2. Open a terminal window and run the Appium server (e.g., appium)

  3. Open another terminal window, change its directory to where your appium.txt file is located.

  4. Type irb to launch the interactive Ruby terminal session

  5. Input the following commands one at a time (hitting Enter after each and waiting for the prompt to return control to you)

require 'appium_lib'
caps = Appium.load_appium_txt file: File.join(Dir.pwd, 'appium.txt')
Appium::Driver.new(caps).start_driver
Appium.promote_appium_methods Object

NOTE: There is a library called Appium Ruby Console which takes care of this initial setup for you, but it's not officially supported by the Appium project. Using irb is recommended since it will remain stable and more closely resembles the code you need to write in your actual tests.

After you've executed all of the commands, you will have a window with your app loaded that you can interact with manually, as well as an interactive command-prompt for Appium that you can issue commands to. To end the Appium client session, you can issue a driver.quit command and end the irb session with the quit command.

An iOS Example

To get a quick birds eye view of our iOS app structure, let's get a list of the various element classes available. With the page_class command we can do just that.

[1] pry(main)> page_class
20x XCUIElementTypeStaticText
10x XCUIElementTypeCell
10x XCUIElementTypeOther
2x XCUIElementTypeWindow
1x XCUIElementTypeStatusBar
1x XCUIElementTypeNavigationBar
1x XCUIElementTypeTable
1x XCUIElementTypeApplication

With the page command we can specify a class name and see all of the elements for that type. When specifying the element class name, we can either specify it as a string, or a symbol (e.g., 'XCUIElementTypeStaticText' or :XCUIElementTypeStaticText).

[2] pry(main)> page :XCUIElementTypeStaticText
XCUIElementTypeStaticText
   name, label, value: UICatalog
   hint:
XCUIElementTypeStaticText
   name, label, value: Action Sheets
   hint:
XCUIElementTypeStaticText
   name, label, value: AAPLActionSheetViewController
   hint:
XCUIElementTypeStaticText
   name, label, value: Activity Indicators
   hint:
...

Within each element of the list, notice their properties — things like name, label, and value. This is the kind of information we will want to reference in order to interact with the app. Let's take the second element for example:

XCUIElementTypeStaticText
   name, label, value: Action Sheets
   hint:

In order to find this element and interact with it, we can can search for it with a couple of different commands: find, text, or text_exact.

[3] pry(main)> find('Action Sheets')
#<Selenium::WebDriver::Element:0x43a1194018243038 id="71760D5F-FFA7-4379-BF4A-41048BB87F99">

We'll know that we successfully found an element when we see a Selenium::WebDriver::Element object returned. To verify that we have the element we expect, let's access the name attribute for it.

[4] pry(main)> find('Action Sheets').name
"Action Sheets"

An Android Example

To get a quick birds eye view of our Android app structure, let's get a list of the various element classes available. With the page_class command we can do just that.

[1] pry(main)> page_class
11x android.widget.TextView
5x android.widget.FrameLayout
2x android.widget.LinearLayout
2x android.view.ViewGroup
1x android.widget.ListView
1x android.widget.ImageView
1x hierarchy

With the page command, we can specify a class name and see all of the elements for that type. When specifying the element class name, we can specify it as a string (e.g., 'android.widget.TextView').

[2] pry(main)> page 'android.widget.TextView'

android.widget.TextView (0)
  text: API Demos
  strings.xml: activity_sample_code

android.widget.TextView (1)
  text, desc: Access'ibility
  id: android:id/text1

android.widget.TextView (2)
  text, desc: Accessibility
  id: android:id/text1

android.widget.TextView (3)
  text, desc: Animation
  id: android:id/text1
...

Within each element of the list, notice their properties -- things like name, label, and value. This is the kind of information we will want to reference in order interact with the app. Let's take the third element for example:

android.widget.TextView (2)
  text, desc: Accessibility
  id: android:id/text1

In order to find that element and interact with it, we can search for it by text or by id. Since there are no unique IDs, we'll use text.

[3] pry(main)> text('Accessibility')
#<Selenium::WebDriver::Element:0x21934249d0953622 id="1">

We'll know that we successfully found an element when we see a Selenium::WebDriver::Element object returned. To verify that we have the element we expect, let's access the name attribute for it.

[4] pry(main)> text('Accessibility').name
"Accessibility"

Using the Appium Desktop App

Run the Appium server through Appium Desktop app by clicking Start Server with the defaults provided. Once it's running, you should see a log window listing the latest server activity.

NOTE: If you have Appium running in a terminal window you'll need to kill it by issuing a CTRL+C command.

Appium Desktop init

Appium Desktop running

Click Start New Session at the top of the screen and specify your capabilities manually (the same as you've specified in your appium.txt file). Then click Start Session.

NOTE: You can save your configuration by clicking the Save As button next to Start Session and giving it a helpful name. Then you can refer to this configuration easily later.

Appium Desktop with Manual Caps

NOTE: Alternatively, you can take advantage of Appium Desktop's ability to connect to an already running session. To do that, you'll need to grab the session of ID of the already running Appium session (which is available in the Appium Server log output), click Start New Session, paste the ID into the Attach to Session... menu option, and click Attach to Session.

When the session is fully loaded, a three-pane inspector window will open that shows a screenshot of the app on the left, the underlying source code of the app's UI in the center, and details about the element you are attempting to interact with on the right.

Appium Desktop Inspector init

In the left-pane you can click on an element you'd like to interact with. When you do, the middle pane will update with the source code. The right-pane will then show details about the element and offer actions you can take against it (e.g., Tap or Send Keys).

Appium Desktop Inspector Drill Down

Section 4

Commands and Operations

The most common operations you'll end up doing in Appium are finding an element (or a set of elements) and performing actions with those elements (e.g. tap, type text, swipe, etc.). You can also ask questions about the elements (e.g. Is it displayed? Is it enabled? etc.), pull information out of the element (e.g. the text of an element or the text of a specific attribute within an element), or perform additional gestures.

Finding an Element

# find just one, the first one Appium finds
element = find('locator')

# find all instances of the element on the page
element = finds('locator')

Work With a Found Element

# chain actions togethers
find('locator').click

# store the element and then click it
element = find('locator')
element.click

Perform Multiple Commands

element.click  # clicks an element
element.clear  # clears an input field
element.send_keys('input text') # type text into an input field

Ask a Question

element.displayed?  # is it visible to the user?
element.enabled?    # can it be selected by the user?

Retrieve Information

# directly from an element
element.text

# by an attribute name
element.attribute('clickable')

Gestures

# Swipe (by Coordinates)
swipe start_x: 75, start_y: 500, end_x: 75, end_y: 0, duration: 0.8

# Swipe (by Locators)
start   = find('starting-element-locator').location.to_h
finish  = find('ending-element-locator').location.to_h
Appium::TouchAction.new.press(start).wait(200).move_to(finish).release.perform

# Long Press
element = find('locator').location.to_h
location.merge!(fingers: 1, duration: 2000
Appium::TouchAction.new.long_press(button).release.perform

NOTE: For a full list of available commands and operations, be sure to check out the documentation.

An Example Test

To tie all of these concepts together, here is a simple test that demonstrates how to use Appium to exercise common functionality by launching an app, navigating through it, triggering an alert, dismissing the alert, and waiting for the app to return to the previous screen.

require 'appium_lib'

describe 'Alert' do

  before(:each) do
    caps = Appium.load_appium_txt file: File.join(File.dirname(__FILE__), 'appium.txt')
    Appium::Driver.new(caps).start_driver
    Appium.promote_appium_methods RSpec::Core::ExampleGroup
  end

  after(:each) do
    driver.quit
  end

  it 'open and closed' do
    text('Alerts').click
    text('Show Simple').click
    id('OK').click
    wait { text('Show Simple') }
  end

end
Section 5

Available Drivers

To run your Appium tests on a different platform, platform version, or driver, you'll need to specify certain capabilities. Here's a breakdown.

platfornName

automationName

Description

iOS

not required

the instruments driver (up to iOS 9.3)

iOS

XCUITest

the XCUITest driver (for iOS 9.3+)

iOS

YouiEngine

the You.i.Engine driver

Android

not required

the UiAutomator driver

Android

UiAutomator2

the UiAutomator2 driver

Android

Selendroid

the Selendroid driver

Android

YouiEngine

the You.i.Engine driver

Windows

not required

the Windows WinAppDriver

Mac

not required

the Appium4Mac driver

NOTE: For more details on what's supported within Appium, take a look at the Appium Design documentation.

Section 6

Appium Service Providers

Rather than take on the overhead of standing up and maintaining a test infrastructure, you can easily outsource these services to a third-party cloud provider like Sauce Labs. With Sauce Labs you'll also be able to get access to real devices as well as simulators and emulators.

NOTE: You'll need an account to use Sauce Labs. Their free trial offers enough to get you started. And if you're signing up because you want to test an open source project, then be sure to check out their Open Sauce account.

In the Appium Ruby bindings this is a turn-key thing to enable within appium.txt. You just need to provide your Sauce username (which you use to log in) and access key (which is available under the My Account page in your Account Dashboard). You will also need to specify where your test app is located (either at a publicly available URL or uploaded into the Sauce cloud).

app = "https://github.com/appium/ruby_lib/raw/master/android_tests/api.apk"
# ...
[appium_lib]
sauce_username = 'your-sauce-username'
sauce_access_key = 'your-sauce-access-key'

Alternatively, you can bypass the appium.txt file and specify your configuration as part of your test setup code.

  # ...
  before(:each) do
    caps = {
      caps: {
        platformName: "Android",
        deviceName: "Android Emulator",
        platformVersion: '6.0',
        app: "https://github.com/appium/ruby_lib/raw/master/android_tests/api.apk" },
      appium_lib: {
        sauce_username: ENV['SAUCE_USERNAME'],
        sauce_password: ENV['SAUCE_PASSWORD'] }
    }

    Appium::Driver.new(caps).start_driver
    Appium.promote_appium_methods RSpec::Core::ExampleGroup
  end
  # ...

NOTE: Also, you can spin up a Sauce Labs session from within the Appium Desktop app's Start New Session menu. After providing your credientials, specify the caps for the setup you need and click Start Session.

NOTE: You can see a full list of Sauce Labs' available platform options here. There's also a handy configuration generator which will tell you what values to plug into your test. Be sure to check out Sauce Labs' documentation portal for more details.

Publications

  • Featured
  • Latest
  • Popular
DOWNLOAD
Design Patterns
Learn design patterns quickly with Jason McDonald's outstanding tutorial on the original 23 Gang of Four design patterns, including class diagrams, explanations, usage info, and real world examples.
205.9k 591k
DOWNLOAD
Core Java
Gives you an overview of key aspects of the Java language and references on the core library, commonly used tools, and new Java 8 features.
127k 349.7k
DOWNLOAD
Getting Started with Ajax
Introduces Ajax, a group interrelated techniques used in client-side web development for creating asynchronous web applications.
101.8k 212.7k
DOWNLOAD
Getting Started with Git
This updated Refcard explains why so many developers are migrating to this exciting platform. Learn about creating a new Git repository, cloning existing projects, the remote workflow, and more to pave the way for limitless content version control.
116.4k 274.2k
DOWNLOAD
Foundations of RESTful Architecture
The Representational State Transfer (REST) architectural style is a worldview that elevates information into a first-class element of architectures. REST allows us to achieve the architectural properties of performance, scalability, generality, simplicity, modifiability, and extensibility. This newly updated Refcard explains main HTTP verbs, describes response codes, and lists libraries and frameworks. It also gives additional resources to further explore each topic.
101k 169.5k
DOWNLOAD
Spring Configuration
Catalogs the XML elements available as of Spring 2.5 and highlights those most commonly used: a handy resource for Spring context configuration.
103.6k 263.5k
DOWNLOAD
Core CSS: Part I
Covers Core principles of CSS that will expand and strengthen your professional ability to work with CSS. Part one of three.
90.5k 198.4k
DOWNLOAD
Scrum
Scrum is a framework that allows people to productively and creatively deliver products of the highest possible value. With over 70% of Agile teams using Scrum or Scrum hybrid, learn more about its benefits in managing complex product development. This newly updated Refcard explores the details of Scrum, including theory, values, roles, and events. It also includes a sample of a popular approach to deliver Integrated Increments in a scaled environment.
93.9k 248.6k
DOWNLOAD
jQuery Selectors
Introduces jQuery Selectors, which allow you to select and manipulate HTML elements as a group or as a single element in jQuery.
93.4k 356.4k
DOWNLOAD
Core Java Concurrency
Helps Java developers working with multi-threaded programs understand the core concurrency concepts and how to apply them.
90.5k 192.3k
DOWNLOAD
Getting Started with Eclipse
Eclipse IDE is a cross-platform, multi-purpose, open-source Integrated Development Environment. It is widely used to develop projects in Java, JavaScript, PHP, C++, Scala, and many others. This newly updated Refcard breaks down installing, setting up, and getting started with Eclipse. It also covers productivity tips, creating new projects and files, accessing Source Control Managers, and debugging configurations.
79.2k 215.1k
DOWNLOAD
Core CSS: Part II
Covers Core principles of CSS that will expand and strengthen your professional ability to work with CSS. Part two of three.
73.8k 141.6k
{{ card.title }}
{{card.downloads | formatCount }} {{card.views | formatCount }}
THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}