Appium automates native, hybrid and mobile-web apps on Android and iOS using the same WebDriver API you know from Selenium. This tutorial covers how Appium works, setting it up, writing the first test, locating elements and performing gestures, and handling hybrid apps. For interview preparation, see the 25 Appium interview questions.
How Appium Works
Your test (Java client) sends W3C WebDriver commands to the Appium server. The server passes each command to a driver for the platform: UiAutomator2 for Android or XCUITest for iOS, which uses the platform's own automation framework to act on the device and returns the result.
Setup (Appium 2)
npm install -g appium
appium driver install uiautomator2 # Android
appium driver install xcuitest # iOS (macOS only)
appium # starts the server on http://127.0.0.1:4723
Android also needs the Android SDK with an emulator or a device with USB debugging enabled; iOS needs a Mac with Xcode. Add the io.appium:java-client dependency to your Maven project.
First Android Test
UiAutomator2Options options = new UiAutomator2Options()
.setDeviceName("Pixel_7_API_34")
.setApp(System.getProperty("user.dir") + "/apps/app-debug.apk");
AndroidDriver driver = new AndroidDriver(new URL("http://127.0.0.1:4723"), options);
try {
driver.findElement(AppiumBy.accessibilityId("username")).sendKeys("asha");
driver.findElement(AppiumBy.accessibilityId("password")).sendKeys("secret");
driver.findElement(AppiumBy.accessibilityId("login")).click();
assertTrue(driver.findElement(AppiumBy.accessibilityId("welcome")).isDisplayed());
} finally {
driver.quit();
}
Locators and Gestures
- Prefer accessibility IDs (content-desc on Android, accessibilityIdentifier on iOS), then resource IDs; avoid long XPath, which is slow on mobile.
- Scrolling on Android:
AppiumBy.androidUIAutomator("new UiScrollable(new UiSelector().scrollable(true)).scrollIntoView(new UiSelector().text(\"Settings\"))") - Gestures: use W3C actions or driver commands such as
mobile: swipeGesture; the old TouchAction API is deprecated.
Mobile Testing with Appium: Core Questions
What is Appium? How does it differ from Selenium?
| Appium | Selenium WebDriver |
|---|---|
| Mobile automation — iOS and Android | Web automation — desktop browsers |
| Uses UIAutomator2 (Android) and XCUITest (iOS) | Uses ChromeDriver, GeckoDriver, EdgeDriver |
| Supports native, hybrid, and mobile web apps | Supports web apps only |
| No app source code modification needed | No app modification needed either |
| Extends WebDriver protocol for mobile | Original WebDriver W3C protocol |
| Requires Appium Server + device/emulator | Requires browser + browser driver only |
What are Desired Capabilities in Appium? List key ones for Android.
✔ Desired Capabilities (or Options) tell Appium which device and app to use.
- platformName: 'Android' — required, specifies mobile OS
- deviceName: 'emulator-5554' or 'Samsung Galaxy S21' — target device
- appPackage: 'com.amazon.mShop.android.shopping' — app package name
- appActivity: 'com.amazon.mShop.android.activity.MainActivity' — launch activity
- automationName: 'UIAutomator2' — Appium automation driver for Android
- app: '/path/to/app.apk' — specify if app is not already installed
- noReset: true — don't reset app state between sessions (faster)
- autoGrantPermissions: true — automatically grant app permissions
What locator strategies are specific to Appium mobile testing?
✔ Appium supports standard Selenium locators plus mobile-specific ones.
- accessibility id (BEST): Maps to contentDescription (Android) and accessibilityLabel (iOS)
driver.findElement(AppiumBy.accessibilityId("Search"));- -android uiautomator: Powerful Android-specific selector
- new UiSelector().text("Login").className("android.widget.Button")
- -ios predicate string: iOS NSPredicate-based queries
"name == 'Login' AND type == 'XCUITypeButton'"- -ios class chain: Faster than predicate for iOS
"**/XCUIElementTypeButton[`name == 'Login'`]"- xpath: Works but slower on mobile — use as last resort
iOS Testing and Context Switching
What are the key capabilities for iOS in Appium? How do you set up an iOS test?
iOS automation requires a Mac machine and uses XCUITest driver. The setup is more complex than Android.
PREREQUISITES for iOS
macOS machine (mandatory — iOS tools only work on Mac)
Xcode installed from App Store
Appium server: npm install -g appium
XCUITest driver: appium driver install xcuitest
For simulator: no Apple account needed
For real device: Apple Developer account + provisioning profile + code signing cert
iOS CAPABILITIES (XCUITestOptions):
XCUITestOptions options = new XCUITestOptions();
options.setPlatformName("iOS");
options.setPlatformVersion("17.0");
options.setDeviceName("iPhone 15 Pro"); // simulator name
options.setAutomationName("XCUITest"); // mandatory
options.setBundleId("com.example.myapp"); // for pre-installed app
// OR: options.setApp("/path/to/MyApp.app"); // install and launch
options.setUdid("auto"); // 'auto' picks available sim
options.setAutoAcceptAlerts(true); // auto-dismiss system alerts
options.setWdaLocalPort(8100); // WebDriverAgent port
options.setUseNewWda(false); // reuse WDA (faster startup)
IOSDriver driver = new IOSDriver(new URL("http://127.0.0.1:4723"), options);
- iOS LOCATORS:
driver.findElement(AppiumBy.accessibilityId("Login")); // best — maps to accessibilityLabel
driver.findElement(AppiumBy.iOSNsPredicateString("name == \"Login\" AND type == \"XCUIElementTypeButton\""));
driver.findElement(AppiumBy.iOSClassChain("**/XCUIElementTypeButton[`name == \"Login\"`]"));
- iOS GESTURES:
driver.executeScript("mobile: swipe", ImmutableMap.of("direction", "up"));
driver.executeScript("mobile: pressButton", ImmutableMap.of("name", "home"));
driver.executeScript("mobile: pressButton", ImmutableMap.of("name", "volumeup"));
iOS vs Android KEY DIFFERENCES
iOS: bundleId vs Android: appPackage + appActivity
iOS: XCUITest driver vs Android: UIAutomator2 driver
iOS: Requires Mac vs Android: Windows/Linux/Mac all work
iOS: WebDriverAgent (WDA) installed on device vs Android: uses ADB
How do you handle hybrid apps in Appium? Explain context switching with a full example.
Hybrid apps contain both native UI and WebView components. You must switch context to interact with each part.
WHAT IS CONTEXT
NATIVE_APP — interact with native UI elements (buttons, lists, etc.)
WEBVIEW_com.example.app — interact with web content inside WebView
STEP 1 — Get all available contexts
Set<String> contexts = driver.getContextHandles();
System.out.println(contexts);
// Output: [NATIVE_APP, WEBVIEW_com.example.myapp]
STEP 2 — Wait for WebView to be available
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(15));
wait.until(d -> d.getContextHandles().size() > 1);
STEP 3 — Switch to WebView
String webviewContext = driver.getContextHandles().stream()
.filter(c -> c.startsWith("WEBVIEW"))
.findFirst()
.orElseThrow(() -> new RuntimeException("WebView context not found"));
driver.context(webviewContext);
STEP 4 — Use Selenium-style locators in WebView
driver.findElement(By.id("webLoginBtn")).click(); // By.id, By.cssSelector etc.
driver.findElement(By.cssSelector(".web-form input[name=\"email\"]")).sendKeys("test@test.com");
STEP 5 — Switch back to native
driver.context("NATIVE_APP");
driver.findElement(AppiumBy.accessibilityId("Back")).click(); // native locators again
GET CURRENT CONTEXT
String current = driver.getContext(); // returns current context name
- ANDROID REQUIREMENT for WebView debugging:
App must enable: WebView.setWebContentsDebuggingEnabled(true)
Set chromedriver: options.setChromedriverExecutableDir("/path/to/chromedriver/");
Match chromedriver version with WebView Chrome version on device
- iOS WebView:
Uses Safari WebInspector — no chromedriver needed
Enable: iOS Settings → Safari → Advanced → Web Inspector ON
FAQs
Is Appium the same as Selenium?
Appium uses the same WebDriver protocol and client style as Selenium, but it automates mobile apps through platform drivers such as UiAutomator2 and XCUITest instead of browsers.
Do I need a Mac to test iOS apps with Appium?
Yes. The XCUITest driver depends on Xcode, which only runs on macOS; Android testing works on Windows, macOS or Linux.
Should I use emulators or real devices?
Use emulators and simulators for everyday automated runs, and real devices (or a device cloud) for performance, hardware features and final release checks.