Android/iOS Testing Perfected: 20 Appium Tricks You Need

Android/iOS Testing Perfected: 20 Appium Tricks You Need

Backer posted 5 min read

Appium is one of the(maybe number one) most popular open-source automation tool for testing mobile applications across iOS and Android platforms. Strong libraries, wide community and documentation support and years of experience across all the QA Enginners and most importantly Selenium-like syntax makes it top choice for Native Mobile App testing. If we know that, we should know how to make it perfect too.

Appium Best Practices & Tips

1. Use Appium Inspector

Appium Inspector helps in identifying element locators efficiently. It allows testers to inspect UI elements and retrieve attributes like resource-id, accessibility-id, text, and class.

Example:

  1. Open Appium Inspector and connect to your running session.
  2. Click on elements to fetch their properties.
  3. Copy unique locators to use in your automation script, ensuring better test stability.

2. Find Exact App Names from Play Store

To correctly launch an app using Appium, you need the exact package name and main activity.

Example:

  1. Install the "Package Name Viewer" on an android test device.

  2. Use these details in your capabilities while setting up Appium.

3. Download trusted APKs

Some APK needs to be downloaded from external instead of play store. You should ALWAYS double check what you downloaded on your VD. It may not be seem harmful, but your work environment can contain sensitive information as usual.

Example:

adb install "C:\Users\YourUserName\Downloads\may-be-malware.apk"

If you dont trust, open new virtual device and do not login your google account or elsewhere, then test the app there.

4. Advanced ADB Command for Extracting Current Activity

Instead of manually searching the activity name from dumpsys window, use the following command to extract it precisely:

Example:

adb shell dumpsys window | grep -oP '(?<=mCurrentFocus=Window{)[^}]+'

This command extracts only the currently focused window, making it easier to grab the package and activity for use in Appium tests.

5. Disable Animations via ADB

Animations can slow down tests and cause flakiness. Disable them using ADB commands.

Example:

adb shell settings put global window_animation_scale 0
adb shell settings put global transition_animation_scale 0
adb shell settings put global animator_duration_scale 0

This speeds up UI interactions during automation.

6. Page Object Model (POM) Configurations

Using POM makes test scripts more structured and maintainable by separating UI elements and test logic.

But you cannot use constructor as you used in Selenium before. AppiumFieldDecorator is MUST due to its own lazy load handle nature. Its also good practice and sometimes we should go with @AndroidFindBy annotation(iOS has also its own @iOSFindBy annotation) instead of Seleniums @FindBy annotation. Because it has just 8 locators and uiAutomator and accessibility not one of them.

Example:

public abstract class LandingPage {

    public LandingPage() {
        PageFactory.initElements(new AppiumFieldDecorator(getDriver()), this);
    }

    @AndroidFindBy(accessibility = "Login Screen")
    public WebElement loginScreen;

    @AndroidFindBy(accessibility = "Echo Box")
    public WebElement echoBoxScreen;

TL&DR; following this structure makes test cases more readable and reusable.

7. Prefer Accessibility IDs and Resource IDs

Accessibility ID and Resource ID are the most reliable locators compared to XPaths, making tests more stable and faster.

Example:

driver.findElement(MobileBy.AccessibilityId("SubmitButton")).click();

This avoids issues caused by UI structure changes.

8. Handle Flakiness with Retries

Tests may fail due to temporary issues like slow network or animations. Implement retry logic to reduce false failures.

Example:

@Test(retryAnalyzer = RetryAnalyzer.class)
public void testLogin() {
    // Test implementation
}

This improves test reliability.

9. Explicit Waits

Avoid using Thread.sleep() as it introduces unnecessary delays. Instead, use explicit waits, which wait for an element until a specified condition is met.

Example:

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("login_button")));

This ensures that your test does not proceed until the element is visible.

10. Parallel Test Execution

Run tests on multiple devices simultaneously to speed up execution.

Example:

<suite name="ParallelTests" parallel="tests" thread-count="2">
    <test name="AndroidTest1">
        <classes>
            <class name="tests.LoginTest" />
        </classes>
    </test>
</suite>

This optimizes test execution time.

11. Use UIAutomator2

UIAutomator2 is the recommended automation engine for Android as it provides better stability and speed.

Example (Java):

capabilities.setCapability("automationName", "UIAutomator2");

This ensures compatibility with modern Android versions.

12. Network Conditioning

Simulate different network conditions like slow or no internet to test app behavior.

Example:

adb shell am broadcast -a com.android.intent.action.SET_NETWORK_CONDITIONS --es condition slow

This helps validate app performance under various network conditions.

13. Grant Permissions via ADB

Some apps require runtime permissions. Instead of manually accepting popups, grant permissions via ADB.

Example:

adb shell pm grant com.example android.permission.CAMERA

This ensures smooth test execution without interruptions.

14. Screenshots on Failure

Capture screenshots on test failures to debug issues effectively.

Example:

        byte[] screenShots = Driver.getDriver().getScreenshotAs(OutputType.BYTES);

        //Appium will always return screenshot as png
        File saveFile = new File("C:\\Users\\YourPath\\screenshot.png");

        //save to our desktop if needed
        try (FileOutputStream fos = new FileOutputStream(saveFile)) {
            fos.write(screenShots);
        } catch (IOException e) {
            e.printStackTrace();
        }

This helps in analyzing failures visually.

15. Test Data Cleanup

Ensure a fresh app state before every test by resetting app data.

Example:

driver.resetApp();
// Or if you dont have complex use cases and dont want to handle before-after methods at hooks in your Driver class use
options.setNoReset(false);

This prevents stale data from affecting test results.

16. Cloud Testing Services

Use services like BrowserStack, Sauce Labs, or Firebase Test Lab to run tests on real devices in the cloud. It will also help you if you are unable to use Mac machine to test IOS.

Example:

capabilities.setCapability("browserstack.user", "your_username");
capabilities.setCapability("browserstack.key", "your_access_key");

Cloud testing provides access to multiple device configurations and reduces infrastructure costs.

Bonus: iOS Tips

Use xcuitest Automation Engine

For iOS automation, always use the XCUITest automation engine as it is the most stable and widely supported.

Example:

capabilities.setCapability("automationName", "XCUITest");

This ensures better compatibility with iOS devices.

Handle iOS Permissions Automatically

iOS apps require permissions for features like camera and location. You can pre-approve these using Appium capabilities.

Example:

capabilities.setCapability("autoAcceptAlerts", true);

This prevents permission popups from interrupting your tests.

Use Predicate Strings for Locators

Instead of XPaths, use Predicate Strings for better performance and stability.

Example:

driver.findElement(MobileBy.iOSNsPredicateString("label == 'Submit'"));

Predicate Strings execute faster and are more robust than XPath.

Use iosClassChain for Faster Element Finding

For better performance in iOS automation, prefer iosClassChain instead of XPath. It’s more efficient and faster for locating elements.

Example:

driver.findElement(MobileBy.iOSClassChain("**/XCUIElementTypeButton[`label == 'Submit'`]")).click();

This improves execution speed compared to XPath and is more reliable.

Predicate String vs iOSClassChain

  • Use Predicate String when you need more readable and flexible conditions (e.g., filtering by label, value, or name).
  • Use iosClassChain when dealing with deeply nested elements or hierarchical structures (e.g., finding a button inside a specific cell).

TL&DR: Predicate String for simple queries, iosClassChain for complex UI trees.

If performance is a concern, iosClassChain is generally faster than Predicate Strings, especially for deeply nested elements.


Following these best practices will significantly improve the stability, reliability, and efficiency of your Appium-based mobile test automation.

Let me know if you have other tips as well!

0 votes
0 votes

More Posts

Tester's Six Eye Technique: Visual Regression Testing

bugnificentverified - May 2, 2025

The Ultimate Guide to Web Accessibility Testing: From Screen Readers to LighthouseCI

bugnificentverified - Mar 27, 2025

Dog CT Scan Cost: What Pet Parents Need to Know

Huifer - Feb 6

Why Automation Testing Fails Without the Right QA Mindset

UpTech Solution - Oct 4, 2025

Performance of Performance Testing: JMeter Script Optimization with VisualVM

bugnificentverified - Jun 17, 2025
chevron_left

Related Jobs

View all jobs →

Commenters (This Week)

1 comment
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!