Appium Mobile Testing Tutorial: Complete 2026 Guide
Complete Appium mobile testing tutorial for 2026. Setup Android and iOS, write your first test, locators, touch actions, POM, Appium 2.0, and cloud testing.

In this article
- What is Appium?
- Step 1 — Prerequisites
- Step 2 — Install Appium
- Step 3 — Install Drivers
- Step 4 — Set Up an Android Emulator
- Step 5 — Set Up an iOS Simulator (macOS only)
- Step 6 — Your First Android Test
- Step 7 — Your First iOS Test
- Step 8 — Mobile Locator Strategies
- Step 9 — Touch Actions
- Step 10 — Cloud Testing
- Common Patterns
- Best Practices
- Continue your mobile testing journey
- Frequently asked questions
Last updated: June 27, 2026 · 9 min read
This tutorial takes you from zero to running Appium tests on both Android and iOS. You'll learn Appium 2.0 architecture, setup, your first test, locators, gestures, POM, and cloud testing. Pair it with our deeper Appium A to Z Guide and Appium vs Espresso comparison.
What is Appium?
Appium is an open-source mobile test automation framework based on the W3C WebDriver protocol. It supports native, hybrid, and mobile-web apps on Android and iOS. Project docs live at appium.io.
Step 1 — Prerequisites
- Node.js 18 LTS or 20 LTS
- Java 17+ (for Android)
- Xcode 15+ (for iOS, macOS only)
- Android Studio (for Android SDK and emulator)
Step 2 — Install Appium
npm install -g appium
appium --version # Should show 2.xStep 3 — Install Drivers
Appium 2.0 uses driver plugins:
# Android (UiAutomator2)
appium driver install uiautomator2
# iOS (XCUITest)
appium driver install xcuitest
# Verify
appium driver list --installedStep 4 — Set Up an Android Emulator
Use Android Studio's AVD Manager:
- Create an AVD (Android Virtual Device)
- Choose Pixel 7 with API 34
- Boot the emulator once to verify
Step 5 — Set Up an iOS Simulator (macOS only)
xcrun simctl list devices available
xcrun simctl boot "iPhone 15"Step 6 — Your First Android Test
Create tests/test_login.py:
from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
options = UiAutomator2Options()
options.device_name = "Pixel_7_API_34"
options.app = "/path/to/app.apk"
driver = webdriver.Remote("http://127.0.0.1:4723", options=options)
try:
driver.find_element(AppiumBy.ID, "email").send_keys("admin@example.com")
driver.find_element(AppiumBy.ID, "password").send_keys("Sup3rSecret!")
driver.find_element(AppiumBy.ID, "submit").click()
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((AppiumBy.XPATH, "//*[contains(@text, 'Welcome')]"))
)
print("Test passed")
finally:
driver.quit()Run it with python tests/test_login.py.
Step 7 — Your First iOS Test
from appium import webdriver
from appium.options.ios import XCUITestOptions
from appium.webdriver.common.appiumby import AppiumBy
options = XCUITestOptions()
options.device_name = "iPhone 15"
options.platform_version = "17.0"
options.app = "/path/to/app.app"
driver = webdriver.Remote("http://127.0.0.1:4723", options=options)
try:
driver.find_element(AppiumBy.ACCESSIBILITY_ID, "email").send_keys("admin@example.com")
driver.find_element(AppiumBy.ACCESSIBILITY_ID, "password").send_keys("Sup3rSecret!")
driver.find_element(AppiumBy.ACCESSIBILITY_ID, "submit").click()
welcome = driver.find_element(AppiumBy.ACCESSIBILITY_ID, "welcome")
assert "Welcome" in welcome.text
print("Test passed")
finally:
driver.quit()Step 8 — Mobile Locator Strategies
Priority order
| Priority | Locator | When to use |
|---|---|---|
| 1 | accessibility id | Always preferred |
| 2 | Android resource id / iOS name | Stable IDs |
| 3 | XPath | Last resort |
| 4 | class chain (iOS) | Complex hierarchies |
| 5 | UiAutomator selector (Android) | Complex queries |
Android examples
# By resource ID
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,
'new UiSelector().resourceId("com.example:id/submit")').click()
# By text
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,
'new UiSelector().textContains("Submit")').click()iOS examples
# By label
driver.find_element(AppiumBy.IOS_PREDICATE, 'label == "Submit"').click()
# By type and label
driver.find_element(AppiumBy.IOS_PREDICATE,
'type == "XCUIElementTypeButton" AND label == "Submit"').click()Step 9 — Touch Actions
# Tap
driver.tap([(540, 1200)])
# Swipe
driver.swipe(540, 1500, 540, 500, 500)
# Long press
from selenium.webdriver.common.action_chains import ActionChains
element = driver.find_element(AppiumBy.ID, "menu-item")
actions = ActionChains(driver)
actions.click_and_hold(element).pause(1).release().perform()Step 10 — Cloud Testing
Run on BrowserStack or Sauce Labs:
options = UiAutomator2Options()
options.device_name = "Google Pixel 7"
options.platform_version = "14.0"
options.app = "bs://<your-app-hash>"
options.set_capability("bstack:options", {
"userName": "your_username",
"accessKey": "your_access_key",
})
driver = webdriver.Remote(
"https://hub-cloud.browserstack.com/wd/hub",
options=options
)The same cloud-grid pattern works for browser tests — see our Playwright Cloud Testing guide.
Common Patterns
Page Object Model for mobile
class LoginScreen:
def __init__(self, driver):
self.driver = driver
self.email_field = driver.find_element(AppiumBy.ID, "email")
self.password_field = driver.find_element(AppiumBy.ID, "password")
self.submit_button = driver.find_element(AppiumBy.ID, "submit")
def login(self, email, password):
self.email_field.send_keys(email)
self.password_field.send_keys(password)
self.submit_button.click()
return DashboardScreen(self.driver)Multi-platform tests
@pytest.mark.parametrize("platform", ["android", "ios"])
def test_login(platform):
if platform == "android":
options = UiAutomator2Options()
else:
options = XCUITestOptions()
options.app = f"/path/to/{platform}/app"
driver = webdriver.Remote("http://127.0.0.1:4723", options=options)
# ... test logicHybrid app testing
# Switch to webview context
contexts = driver.contexts
driver.switch_to.context(contexts[1])
driver.find_element(By.ID, "web-element").click()
# Switch back to native
driver.switch_to.context(contexts[0])Best Practices
Do
- Set accessibility IDs in app source code
- Use real devices for final validation
- Use emulators for development and CI
- Reset app state between tests
- Adapt the Page Object Model for mobile screens
Don't
- Don't use absolute XPath
- Don't share app state across tests
- Don't run mobile tests on Wi-Fi in CI
- Don't ignore accessibility (legal requirement)
Continue your mobile testing journey
Frequently asked questions
Is Appium still relevant in 2026?
Yes — Appium 2.0 is the standard cross-platform mobile automation framework and is actively maintained.
Can Appium test both Android and iOS?
Yes — the same test code runs on both with Appium 2.0 by swapping UiAutomator2Options for XCUITestOptions.
What's the difference between Appium and Espresso?
Appium is cross-platform (Android + iOS) and black-box. Espresso is Android-only, white-box, and faster — see our Appium vs Espresso comparison.
Do I need a real device for Appium?
For final validation, yes. For development and CI, emulators and simulators are sufficient.
How long does it take to set up Appium?
2–4 hours for first-timers including Android Studio and Xcode setup. Faster on subsequent projects.
Can I use Appium with Python or Java?
Yes — Appium supports Python, Java, JavaScript, C#, and Ruby clients.
Practice these questions
Rehearse Selenium and Playwright automation questions covering framework design, waits, locators and CI/CD.
Was this article helpful?
Keep building your QA edge
Pillar guidesContinue reading

Why Every QA Engineer Must Master CI/CD Pipelines in 2026 (Or Risk Obsolescence)
12 min read
Is Cypress Dead? Analyzing 2026 Playwright Market Share
12 min read
Why Tests Pass Locally But Fail in CI/CD (And the 6 Fixes That Actually Work in 2026)
13 min readJoin the QA Community
Connect with fellow testers, share job leads, and get career advice.
Stop Reinventing the Wheel. Upgrade Your QA Arsenal.
Take your testing skills from beginner to Lead Engineer. Supercharge your daily workflow with our premium digital resources.
- ⚡ Ready-to-use testing strategy templates
- 🔥 Advanced API & UI automation guides
- ⏱️ Save 10+ hours a week on test planning