Home / Blog / Appium Mobile Testing: Android Setup from Scratch

Mobile Testing

Appium Mobile Testing: Android Setup from Scratch

QA Knowledge Hub·2026-04-11·8 min read

Mobile apps are everywhere, and companies hire engineers who can test them programmatically. Appium is the industry-standard open-source framework for automating mobile applications — iOS and Android, native and hybrid.

This guide sets up Appium for Android testing from scratch, writes real tests, and explains the key concepts that come up in SDET interviews.

What Appium Is (and Is Not)

Appium is a test automation framework, not a testing platform. It uses the WebDriver protocol to communicate with mobile devices and simulators — the same protocol Selenium uses for browsers.

What it supports:

  • Android native apps (APK)
  • iOS native apps (IPA)
  • Hybrid apps (WebView-based)
  • Mobile browser testing (Chrome on Android, Safari on iOS)

What it does NOT do:

  • It does not run in the cloud. Cloud execution requires BrowserStack, Sauce Labs, or AWS Device Farm.
  • It does not manage device provisioning.

Prerequisites

Install all of these before starting:

1. Java JDK 17+

Download from adoptium.net. Set JAVA_HOME environment variable.

2. Android Studio

Download from developer.android.com/studio. During installation, include:

  • Android SDK
  • Android Virtual Device (AVD) Manager
  • Intel HAXM (hardware accelerator for emulators)

Set environment variables:

# Add to ~/.bashrc or ~/.zshrc (Mac/Linux)
export ANDROID_HOME=$HOME/Library/Android/sdk  # Mac
export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/platform-tools
export PATH=$PATH:$ANDROID_HOME/tools
# Windows: System Properties → Environment Variables
ANDROID_HOME = C:\Users\YourName\AppData\Local\Android\Sdk
PATH += %ANDROID_HOME%\platform-tools
PATH += %ANDROID_HOME%\emulator

3. Node.js

Download from nodejs.org (LTS version). Required for Appium.

4. Appium

npm install -g appium
appium --version  # Should print 2.x.x

5. Appium UiAutomator2 Driver (for Android)

appium driver install uiautomator2
appium driver list  # Should show uiautomator2 as installed

6. Appium Inspector (GUI for finding locators)

Download from github.com/appium/appium-inspector/releases.

Verify Everything

npx appium-doctor --android

All items should show green checkmarks before proceeding.

Create an Android Emulator

  1. Open Android Studio
  2. Tools → Device Manager → Create Device
  3. Select device: Pixel 7 (or any modern device profile)
  4. Select system image: Android 14 (API 34) — download if not present
  5. Finish. The emulator appears in Device Manager.

Start the emulator:

  • From Android Studio: Click the play button next to the device
  • From command line: emulator -avd Pixel_7_API_34

Verify it is running:

adb devices
# List of devices attached
# emulator-5554   device

Get the App Under Test

For practice, use the ApiDemos app included with Android SDK, or download a purpose-built test app:

# Download Appium's test app
curl -O https://github.com/appium/appium/raw/master/packages/appium/sample-code/apps/ApiDemos-debug.apk

Install it on the emulator:

adb install ApiDemos-debug.apk

Maven Project Setup

Create a new Maven project with this pom.xml:

<dependencies>
    <!-- Appium Java Client -->
    <dependency>
        <groupId>io.appium</groupId>
        <artifactId>java-client</artifactId>
        <version>9.2.3</version>
    </dependency>

    <!-- TestNG -->
    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>7.9.0</version>
        <scope>test</scope>
    </dependency>
</dependencies>

Start the Appium Server

appium

Output:

[Appium] Welcome to Appium v2.x.x
[Appium] Appium REST http interface listener started on 0.0.0.0:4723

Leave this terminal open while running tests.

Write Your First Test

// src/test/java/com/qaknowledgehub/mobile/FirstMobileTest.java
package com.qaknowledgehub.mobile;

import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.options.UiAutomator2Options;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;

public class FirstMobileTest {

    private AndroidDriver driver;

    @BeforeMethod
    public void setUp() throws MalformedURLException {
        UiAutomator2Options options = new UiAutomator2Options();
        options.setPlatformName("Android");
        options.setDeviceName("emulator-5554");           // Match your emulator
        options.setApp("/path/to/ApiDemos-debug.apk");   // Full path to APK
        options.setAppPackage("io.appium.android.apis");
        options.setAppActivity(".ApiDemos");
        options.setAutomationName("UiAutomator2");

        driver = new AndroidDriver(
            new URL("http://127.0.0.1:4723"),
            options
        );
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
    }

    @Test
    public void testAppLaunchesSuccessfully() {
        String currentActivity = driver.currentActivity();
        Assert.assertTrue(
            currentActivity.contains("ApiDemos"),
            "App should launch to ApiDemos activity"
        );
    }

    @Test
    public void testClickFirstMenuItem() {
        // Find the "Animation" option in the list
        WebElement animationItem = driver.findElement(
            By.xpath("//android.widget.TextView[@text='Animation']")
        );
        Assert.assertTrue(animationItem.isDisplayed());
        animationItem.click();

        // Verify we navigated to the Animation screen
        WebElement header = driver.findElement(
            By.xpath("//android.widget.TextView[@text='Animation']")
        );
        Assert.assertTrue(header.isDisplayed());
    }

    @AfterMethod
    public void tearDown() {
        if (driver != null) {
            driver.quit();
        }
    }
}

Appium Locator Strategies

Finding elements in mobile apps is different from web. The key strategies:

UiAutomator2 Locators (Android)

// By resource ID (most reliable — if developers add IDs)
By.id("com.example.app:id/login_button")

// By content description (accessibility label)
By.xpath("//android.widget.ImageButton[@content-desc='Back']")

// By text
By.xpath("//android.widget.TextView[@text='Sign In']")

// By partial text
By.xpath("//android.widget.TextView[contains(@text, 'Welcome')]")

// By class name (broad — use only with index or combined)
By.className("android.widget.EditText")

// UiAutomator2 native selector (fastest)
driver.findElement(AppiumBy.androidUIAutomator(
    "new UiSelector().text(\"Sign In\")"
));

driver.findElement(AppiumBy.androidUIAutomator(
    "new UiSelector().resourceId(\"com.example.app:id/email\")"
));

Finding Locators with Appium Inspector

  1. Start Appium Inspector
  2. Enter capabilities:
    {
      "platformName": "Android",
      "deviceName": "emulator-5554",
      "appPackage": "io.appium.android.apis",
      "appActivity": ".ApiDemos",
      "automationName": "UiAutomator2"
    }
  3. Click "Start Session"
  4. The app screen appears. Click any element to see its attributes — resource-id, content-desc, text, class

Use these attributes to build locators.

Page Object Model for Mobile

// src/main/java/com/qaknowledgehub/mobile/pages/LoginPage.java
package com.qaknowledgehub.mobile.pages;

import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.AppiumBy;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

public class LoginPage {

    private final AndroidDriver driver;
    private final WebDriverWait wait;

    private static final String EMAIL_ID = "com.example.app:id/email";
    private static final String PASSWORD_ID = "com.example.app:id/password";
    private static final String LOGIN_BTN_ID = "com.example.app:id/login_btn";
    private static final String ERROR_ID = "com.example.app:id/error_text";

    public LoginPage(AndroidDriver driver) {
        this.driver = driver;
        this.wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    public void enterEmail(String email) {
        WebElement field = wait.until(
            ExpectedConditions.visibilityOfElementLocated(AppiumBy.id(EMAIL_ID))
        );
        field.clear();
        field.sendKeys(email);
    }

    public void enterPassword(String password) {
        driver.findElement(AppiumBy.id(PASSWORD_ID)).sendKeys(password);
    }

    public void tapLoginButton() {
        driver.findElement(AppiumBy.id(LOGIN_BTN_ID)).click();
    }

    public void login(String email, String password) {
        enterEmail(email);
        enterPassword(password);
        tapLoginButton();
    }

    public String getErrorMessage() {
        return driver.findElement(AppiumBy.id(ERROR_ID)).getText();
    }
}

Common Mobile Test Scenarios

Scrolling

// Scroll down to find an element not visible on screen
driver.findElement(AppiumBy.androidUIAutomator(
    "new UiScrollable(new UiSelector().scrollable(true))" +
    ".scrollIntoView(new UiSelector().text(\"Settings\"))"
));

Handling Keyboard

// Hide the keyboard after typing
driver.hideKeyboard();

Swipe Gestures (Appium 2.x)

import io.appium.java_client.android.nativekey.AndroidKey;
import io.appium.java_client.android.nativekey.KeyEvent;

// Press Back button
driver.pressKey(new KeyEvent(AndroidKey.BACK));

// Press Home button
driver.pressKey(new KeyEvent(AndroidKey.HOME));

Getting Device Info

// Get app state
ApplicationState state = driver.queryAppState("io.appium.android.apis");
// ApplicationState.RUNNING_IN_FOREGROUND

// Get current activity
String activity = driver.currentActivity();  // ".ApiDemos"

// Get device details
String platformVersion = driver.getCapabilities()
    .getCapability("platformVersion").toString();

Taking Screenshots

File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenshot, new File("screenshots/test_" + System.currentTimeMillis() + ".png"));

Running on a Real Device

  1. Enable Developer Options on the Android device (tap "Build Number" 7 times in Settings → About Phone)
  2. Enable USB Debugging in Developer Options
  3. Connect device via USB
  4. Run adb devices — your device should appear

Update the deviceName capability to match the device ID shown by adb devices.

Appium Interview Questions

Q1: What is the difference between Appium and Selenium?

Both use the WebDriver protocol. Selenium automates web browsers. Appium automates mobile applications (native, hybrid, and mobile browsers). Appium extends the WebDriver spec with mobile-specific commands (gestures, device key events, app state management).

Q2: What is UiAutomator2?

UiAutomator2 is Google's automation framework for Android, used by Appium as the underlying driver for Android test automation. It is faster and more reliable than the older UiAutomator1 driver.

Q3: What is the difference between a native app, hybrid app, and mobile web?

  • Native: Built specifically for Android (Java/Kotlin) or iOS (Swift/Obj-C). Full device API access.
  • Hybrid: A web app (HTML/CSS/JS) embedded in a native wrapper using WebView. Appium can switch between native context and WebView context.
  • Mobile Web: A website accessed through a mobile browser. Tested using Appium's mobile browser support.

Q4: How do you find elements in a mobile app that has no resource IDs?

Use XPath with text attributes, content descriptions, or class names. As a last resort, use coordinate-based tap actions — but these are fragile and should be avoided.

Q5: How do you handle a test that requires the app to be in a specific state?

Use Appium's activateApp() to bring the app to foreground, terminateApp() to close it, or installApp() to reinstall a fresh version. For test data, use the device's file system or API calls to set up state before the test.

Summary

Appium for Android requires more setup than web automation, but the concepts transfer directly — Page Object Model, explicit waits, locator strategies — all apply.

The key investment is getting the environment right. Once the emulator is running and adb devices shows a connected device, the actual test code is straightforward.

Your next steps:

  1. Get the emulator running and appium doctor showing all green
  2. Download the Appium test app and install it
  3. Run the first test from this guide
  4. Use Appium Inspector to explore the app's element tree
  5. Write 5 tests covering different screens

Mobile testing is a less crowded skill than Selenium web automation. Learning it makes you a more complete SDET candidate.

Recommended Resource

Automation Testing Scenarios Pack

High-quality automation scenarios for UI, API, and microservices systems.

1299Get This Guide →

Related Posts

📝
Interview Prep
Apr 2026·12 min read

35 Playwright Interview Questions (With Answers)

Playwright interview questions and answers for QA and SDET roles — covering setup, locators, waits, fixtures, API testing, and debugging.

Read article →
📝
Selenium
Apr 2026·8 min read

Page Object Model in Selenium: Design and Best Practices

Learn the Page Object Model design pattern for Selenium — why it exists, how to implement it correctly in Java, and the mistakes to avoid.

Read article →
📝
Interview Prep
Apr 2026·11 min read

60 Selenium Interview Questions for Java Developers

The most asked Selenium + Java interview questions with complete answers — covering WebDriver setup, locators, waits, POM, TestNG, and framework design.

Read article →