Tutorial: Learn Appium from Scratch (2026)
I remember the frustration of testing a mobile app manually on a dozen devices. Each OS version behaved differently, and bugs slipped through constantly. Appium changed everything by providing a unified automation framework for iOS and Android that uses the same WebDriver protocol I already knew from Selenium.
Appium is the industry standard for mobile test automation. It supports native, hybrid, and mobile web applications across iOS and Android. In this tutorial, you will learn how to set up Appium, write tests for both platforms, handle gestures, and integrate with cloud device labs for scalable testing.
Setting Up Appium and Your First Mobile Test
Appium runs as a server that receives WebDriver commands and translates them to platform-specific automation APIs. Install Appium via npm: npm install -g appium. For iOS, you need Xcode and the iOS driver plugin. For Android, install the Android SDK and set ANDROID_HOME.
Desired capabilities configure the session — platformName, deviceName, app path, and automationName. For Android, the default automation engine is UiAutomator2. For iOS, use XCUITest. Start the Appium server, then connect with an AppiumDriver to interact with the device.
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability("platformName", "Android");
caps.setCapability("deviceName", "Pixel 6");
caps.setCapability("app", "/path/to/app.apk");
caps.setCapability("automationName", "UiAutomator2");
AndroidDriver driver = new AndroidDriver(new URL("http://localhost:4723"), caps);
Locating Elements on Mobile
Mobile element locators differ from web automation. Appium supports standard WebDriver locators plus mobile-specific ones: accessibility ID (content-desc on Android, accessibilityIdentifier on iOS), XPath, class name, and UI Automator selectors on Android.
Accessibility IDs are the most reliable locators because they are less likely to change. XPath works but is slower on mobile. For Android, use the UiScrollable class to find elements in scrollable views. For iOS, use -ios predicate string and -ios class chain for complex queries.
// Android - accessibility ID
MobileElement loginBtn = (MobileElement) driver.findElementByAccessibilityId("loginButton");
loginBtn.click();
// iOS - predicate string
MobileElement field = (MobileElement) driver.findElementByIosNsPredicate("label BEGINSWITH 'Email'");
field.sendKeys("user@example.com");
Handling Mobile Gestures
Mobile apps rely on gestures — tap, swipe, scroll, pinch, zoom, and long press. Appium provides the TouchAction and MultiTouchAction classes to compose complex gesture sequences. The W3C Actions API is the modern approach and is preferred over the older JSONWP protocol.
Use swipe to scroll through lists, drag-and-drop to rearrange items, and pinch-to-zoom for maps and images. I maintain a GestureUtils class that wraps common gestures with sensible defaults. This keeps test code clean and focuses on business logic.
// Swipe gesture
Dimension size = driver.manage().window().getSize();
int startX = size.width / 2;
int startY = (int) (size.height * 0.8);
int endY = (int) (size.height * 0.2);
new TouchAction(driver)
.press(PointOption.point(startX, startY))
.waitAction(WaitOptions.waitOptions(Duration.ofMillis(500)))
.moveTo(PointOption.point(startX, endY))
.release()
.perform();
Native vs Hybrid vs Mobile Web Testing
Appium handles three application types. Native apps are built with platform SDKs — Swift/Kotlin. Hybrid apps wrap web content in a WebView — Ionic, React Native. Mobile web tests automate the browser — Safari on iOS, Chrome on Android.
For hybrid apps, switch to the WebView context using driver.getContextHandles(). Once in the WebView, use standard Selenium WebDriver commands. I test the native shell (login screens, permissions) with Appium native commands, and the in-app web content with WebDriver commands inside the WebView context.
// Switch to WebView context for hybrid apps
Set contexts = driver.getContextHandles();
for (String context : contexts) {
if (context.contains("WEBVIEW")) {
driver.context(context);
break;
}
}
// Now use WebDriver commands
driver.findElement(By.cssSelector("#email")).sendKeys("user@example.com");
Running Tests on Real Devices and Cloud Labs
Testing on real devices catches issues that emulators miss — battery drain, network switching, interrupt handling. Connect devices via USB or WiFi ADB. For iOS, use the WebDriverAgent that Appium installs on the device for automation.
Cloud device labs like BrowserStack, Sauce Labs, and AWS Device Farm give access to hundreds of real devices. Configure desired capabilities with the cloud provider's settings. The same Appium scripts run locally and in the cloud with a capability change. This scales your mobile testing without hardware investment.
// BrowserStack cloud device
caps.setCapability("browserstack.user", "username");
caps.setCapability("browserstack.key", "accesskey");
caps.setCapability("device", "iPhone 14");
caps.setCapability("os_version", "16");
AndroidDriver driver = new AndroidDriver(
new URL("https://hub-cloud.browserstack.com/wd/hub"), caps);
Appium CI Integration and Best Practices
Running mobile tests in CI requires a device or emulator. Use Docker images for Android emulators or macOS agents for iOS simulators. GitHub Actions supports macOS runners with Xcode. Start the Appium server, create an emulator, run tests, and capture results.
Best practices: use Page Object Model for app screens, implement retry logic for flaky gestures, keep APK/IPA files in artifact storage, and always clean up app data between tests. Video recording of test execution helps debug CI failures that are hard to reproduce locally.
# GitHub Actions - Android
- name: Run Appium Tests
run: |
appium --log-level info &
sleep 5
mvn test -Pandroid
env:
PLATFORM: Android
DEVICE_NAME: Pixel_6_API_33
Frequently Asked Questions
What is the difference between Appium and Espresso/XCUITest?
Appium is a cross-platform automation tool that uses the WebDriver protocol. Espresso (Android) and XCUITest (iOS) are platform-specific frameworks. Appium delegates to these frameworks under the hood but provides a unified API.
Can Appium automate multiple devices simultaneously?
Yes, start multiple Appium server instances on different ports and create separate driver connections. Use parallel test execution frameworks like TestNG or JUnit to coordinate multi-device scenarios.
How do I handle biometric authentication in Appium?
Appium supports fingerprint and face ID through the driver.fingerPrint() method on Android and the ios.touchId() or ios.faceId() commands on iOS using the W3C Actions API.
What is the WebDriverAgent and why is it needed for iOS?
WebDriverAgent is a Facebook-developed proxy that Appium uses to control iOS devices. It runs on the device and translates WebDriver commands into XCUITest calls. Xcode and developer certificates are required for installation.
Originally published on Ayodhyyya. Last updated June 1, 2026.