πŸ“± APPIUM 2.0 MOBILE AUTOMATION

Appium 2.0 Mobile Automation Guide: iOS & Android Setup

Set up modular Appium 2.0 drivers for Android (UiAutomator2) and iOS (XCUITest), configure desired capabilities, and build cross-platform mobile test frameworks.

By Rammehar Dhiman | Mobile QA Specialist Updated July 2026 15 Min Read

Appium 2.0 redesigned mobile test automation by decoupling drivers into independent plugins. Learn how to configure Android emulators, iOS simulators, and write clean Java mobile test scripts.

1. Installing Appium 2.0 and UiAutomator2 Driver

npm install -g appium appium driver install uiautomator2 appium driver install xcuitest appium --version

2. Configuring Android Desired Capabilities for UiAutomator2

import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.android.options.UiAutomator2Options; UiAutomator2Options options = new UiAutomator2Options() .setDeviceName("emulator-5554") .setPlatformVersion("13.0") .setApp(System.getProperty("user.dir") + "/apps/myapp.apk") .setAutoGrantPermissions(true) .setNoReset(false); AndroidDriver driver = new AndroidDriver( new URL("http://127.0.0.1:4723"), options);

3. Writing Your First Appium Test: Login Flow

// Login Test Example: @Test public void testSuccessfulLogin() { WebElement emailField = driver.findElement( AppiumBy.accessibilityId("email-input")); emailField.sendKeys("testuser@example.com"); WebElement passwordField = driver.findElement( AppiumBy.accessibilityId("password-input")); passwordField.sendKeys("Test@12345"); driver.findElement(AppiumBy.accessibilityId("login-btn")).click(); WebElement welcomeMsg = new WebDriverWait(driver, Duration.ofSeconds(10)) .until(ExpectedConditions.visibilityOfElementLocated( AppiumBy.accessibilityId("welcome-message"))); Assert.assertEquals(welcomeMsg.getText(), "Welcome back, Test User!"); }

4. Using UIAutomator2 Inspector (uiautomatorviewer)

The Appium Inspector (previously UIAutomatorViewer) allows QA testers to inspect the Android accessibility tree and identify element locators (ID, AccessibilityId, XPath, ClassName) before writing test scripts. Launch it from appium inspector NPM package.

5. Handling Gestures: Swipe, Scroll, and Pinch-to-Zoom

// Swipe Up to Scroll Down: driver.executeScript("mobile: swipeGesture", Map.of( "left", 100, "top", 1500, "width", 200, "height", 700, "direction", "up", "percent", 0.75));

6. iOS Automation with XCUITest Driver

XCUITestOptions iosOptions = new XCUITestOptions() .setDeviceName("iPhone 15") .setPlatformVersion("17.0") .setBundleId("com.example.myapp") .setWdaLocalPort(8100); IOSDriver iosDriver = new IOSDriver( new URL("http://127.0.0.1:4723"), iosOptions);

7. Page Object Model (POM) for Mobile Tests

Structure Appium tests using the Page Object Model to separate UI element locators from test logic. Use the @AndroidFindBy and @iOSXCUITFindBy annotations from Appium Java Client for cross-platform compatibility.

Frequently Asked Questions (FAQ)

Q1: What is the difference between Appium 1.x and Appium 2.0?

A: Appium 2.0 decouples drivers into independently installable plugins. You only install the drivers you need (UiAutomator2, XCUITest, Espresso) using appium driver install, making the core server lighter and more modular.

Q2: Can Appium test React Native and Flutter apps?

A: Yes. For React Native apps, use standard UiAutomator2/XCUITest drivers. For Flutter apps, use the flutter_driver package or the specialized appium-flutter-driver plugin.

Q3: What is the recommended locator strategy in Appium?

A: Use AccessibilityId (cross-platform) as the first choice since it works on both Android and iOS. Avoid XPath for performance reasons as it performs a full traversal of the accessibility tree.

8. Cross-Platform Testing Strategy: One Codebase, Two Platforms

Appium enables a single Java test class to run on both Android and iOS by using conditional driver initialization and the @AndroidFindBy / @iOSXCUITFindBy annotation pair from Appium Java Client.

// Cross-platform Page Object: public class LoginPage { @AndroidFindBy(accessibility = "email-input") @iOSXCUITFindBy(accessibility = "email-field") private MobileElement emailField; @AndroidFindBy(accessibility = "login-btn") @iOSXCUITFindBy(accessibility = "login-button") private MobileElement loginButton; public void login(String email, String password) { emailField.sendKeys(email); loginButton.click(); } }

9. Running Appium Tests on Real Devices (Cloud Testing Platforms)

For production-grade mobile QA, run Appium tests against real device clouds like BrowserStack, LambdaTest, or Sauce Labs. These platforms provide 3000+ real Android and iOS devices accessible via remote WebDriver URLs.

// BrowserStack Real Device Example: String BROWSERSTACK_URL = "https://USERNAME:ACCESSKEY@hub.browserstack.com/wd/hub"; DesiredCapabilities caps = new DesiredCapabilities(); caps.setCapability("device", "Samsung Galaxy S23"); caps.setCapability("os_version", "13.0"); caps.setCapability("app", "bs://your-uploaded-app-id"); AndroidDriver driver = new AndroidDriver(new URL(BROWSERSTACK_URL), caps);

10. Appium Test Reporting with Allure & Extent Reports

Integrate Allure Report with TestNG to generate step-by-step test evidence including screenshots, device logs, and video recordings. Add the allure-testng Maven dependency and annotate critical steps with @Step("User taps Login button").

πŸ’‘ Hinglish Explanation: Mobile testing mein sabse bada challenge device fragmentation hai. Android ka matlab sirf Android nahi - Samsung, OnePlus, Xiaomi, Vivo β€” sabki screen sizes alag, OS versions alag. Isliye cloud testing platforms jaise BrowserStack bahut important hain. Wahan ek test 100+ real devices par chalaya ja sakta hai.

11. Appium Inspector: Inspecting Element Locators Visually

Before writing locators in your test scripts, use the Appium Inspector tool to visually identify element attributes (resource-id, content-desc, text, className) on the live device or emulator screen. This prevents wasted time writing locators that don't work.

Launch Appium Inspector by running npm install -g appium-inspector, connecting to your Appium server at http://localhost:4723, and entering the desired capabilities. The visual tree viewer shows every accessible element and its attributes in a hierarchical format.

12. Handling Toasts, Alerts & Dialogs in Appium

// Accept Android Native Alert Dialog: driver.switchTo().alert().accept(); // Handle Android Toast Message (using UiAutomator2): WebElement toast = driver.findElement( By.xpath("//android.widget.Toast[1]")); String toastText = toast.getAttribute("name"); Assert.assertEquals(toastText, "Login Successful!");

13. Running Appium Tests in Parallel on Multiple Devices

Use TestNG parallel execution with separate Appium server ports per device to run tests concurrently across multiple Android emulators or real devices. This dramatically reduces overall test suite execution time.

// testng.xml for parallel device execution: // <suite name="Mobile Suite" parallel="tests" thread-count="3"> // <test name="Samsung Galaxy"> // <parameter name="device" value="emulator-5554"/> // </test> // <test name="OnePlus Nord"> // <parameter name="device" value="emulator-5556"/> // </test> // </suite>
πŸ’‘ Hinglish Summary: Appium 2.0 mobile testing ka complete journey: Install β†’ Configure Capabilities β†’ Write Locators via Inspector β†’ Write Tests β†’ Run on Emulator/Real Device β†’ Parallel Execution on Cloud. Yeh process follow karne se aapki mobile QA automation framework industry-ready ho jaati hai.

14. Deep Link Testing with Appium

Deep links allow users to navigate directly to specific screens within a mobile app from external sources (push notifications, email links, websites). Testing deep links is critical for marketing campaigns and notification-driven user flows. In Android, test deep links using the adb command or Appium's driver.executeScript("mobile: deepLink").

// Test Android deep link navigation: driver.executeScript("mobile: deepLink", Map.of( "url", "myapp://products/electronics/101", "package", "com.example.myapp")); // Verify correct screen was opened: WebElement productTitle = new WebDriverWait(driver, Duration.ofSeconds(10)) .until(ExpectedConditions.visibilityOfElementLocated( AppiumBy.accessibilityId("product-title"))); Assert.assertEquals(productTitle.getText(), "Wireless Headphones Pro"); // iOS Universal Link testing: Map<String, Object> iosDeepLink = Map.of( "bundleId", "com.example.myapp", "url", "https://myapp.com/product/101"); driver.executeScript("mobile: launchApp", iosDeepLink);

15. Network Condition Simulation β€” Offline and Slow 3G Testing

Mobile apps must behave gracefully under poor network conditions β€” 3G connectivity, airplane mode, or intermittent WiFi. Appium enables programmatic network condition simulation on Android using the setNetworkConnection API and on iOS through the Network Link Conditioner tool.

Network testing is essential for verifying offline caching, error message display (β€œNo internet connection” screens), retry mechanisms, and data sync behavior when connectivity is restored. These scenarios are frequently missed in desktop browser automation but are critical for mobile QA coverage.

// Android network condition constants: // 0 = Airplane mode, 1 = WiFi off, 2 = Data off, 4 = Airplane off, 6 = All on AndroidDriver androidDriver = (AndroidDriver) driver; // Test offline behavior: androidDriver.setConnection(new ConnectionStateBuilder().withAirplaneModeEnabled().build()); Thread.sleep(1000); // Verify offline error screen appears: WebElement offlineMsg = driver.findElement(AppiumBy.accessibilityId("offline-notice")); Assert.assertTrue(offlineMsg.isDisplayed()); // Restore network connection: androidDriver.setConnection(new ConnectionStateBuilder().withWiFiEnabled().withDataEnabled().build());

16. Mobile App Performance Testing with Appium

Performance testing for mobile apps focuses on three key metrics: app launch time (cold start vs warm start), screen transition latency, and memory consumption over extended usage. Appium's getPerformanceData API for Android and Instruments profiling for iOS provide programmatic access to these metrics during automated test runs.

// Get CPU usage during a specific action (Android): List<List<Object>> cpuData = androidDriver.getPerformanceData( "com.example.myapp", "cpuinfo", 5); System.out.println("CPU Usage: " + cpuData); // Measure cold start time: long startTime = System.currentTimeMillis(); androidDriver.activateApp("com.example.myapp"); new WebDriverWait(driver, Duration.ofSeconds(15)) .until(ExpectedConditions.visibilityOfElementLocated( AppiumBy.accessibilityId("home-screen"))); long launchTime = System.currentTimeMillis() - startTime; Assert.assertTrue(launchTime < 3000, "App launch too slow: " + launchTime + "ms (SLA: 3000ms)");

17. CI/CD Integration for Appium β€” Running Mobile Tests in GitHub Actions

Running Appium tests in CI/CD requires a different approach than web automation because you need either a cloud device farm (BrowserStack, Sauce Labs) or Android emulators running on the CI server. GitHub Actions supports Android emulator execution using the reactivecircus/android-emulator-runner action.

# .github/workflows/mobile-tests.yml name: Appium Mobile Test Suite on: [push, pull_request] jobs: mobile-tests: runs-on: macos-latest # macOS required for iOS simulators steps: - uses: actions/checkout@v3 - name: Set up JDK 17 uses: actions/setup-java@v3 with: java-version: '17' - name: Start Appium Server run: | npm install -g appium appium driver install uiautomator2 appium & - uses: reactivecircus/android-emulator-runner@v2 with: api-level: 33 arch: x86_64 script: mvn test -DsuiteXmlFile=mobile-smoke.xml

18. Common Appium Pitfalls and Production-Proven Fixes

Experienced mobile QA engineers accumulate battle-tested knowledge of Appium’s failure modes. Here are the most frequently encountered pitfalls and their proven solutions:

Appium Interview Questions β€” Mobile Automation SDET Level

Q: How do you decide between testing on emulators vs real devices?

A: Emulators are sufficient for 80% of functional testing β€” fast, free, and reproducible. Reserve real devices for final regression runs, performance validation, network condition testing, and hardware-specific scenarios (camera, fingerprint, NFC). Cloud platforms like BrowserStack provide real device access without hardware maintenance overhead.

Q: How would you structure an Appium framework for a team of 10 QA engineers?

A: Use a Base Test class with thread-safe ThreadLocal<AppiumDriver> for parallel device execution, a ScreenFactory pattern (similar to PageFactory), a CapabilityManager that loads device configs from JSON files (not hardcoded), a DataFactory for test data generation, and Allure reporting with device screenshots attached on failure. Store all capabilities in a devices.json config file that can be modified without code changes.

Q: What is the difference between driver.closeApp() and driver.terminateApp()?

A: closeApp() sends the app to the background (mimicking the home button press) but keeps the session alive and app state preserved. terminateApp(bundleId) force-kills the app process completely, resetting all app state. Use terminateApp in @BeforeMethod to guarantee a clean app start for each test.

References & Official Documentation

✍️ About the Author

Rammehar Dhiman is a Senior Mobile QA Engineer specializing in Appium 2.0, React Native, and Flutter app testing across Android and iOS platforms. He has built mobile automation frameworks for fintech and e-commerce apps serving 10+ million active users.

Summary Checklist for Appium 2.0 Mobile Automation Setup