← Back to Blog

Mobile App Testing with Appium: Best Practices for Android and iOS

Mobile app testing presents unique challenges compared to web testing. With Appium, you can write tests that work across both Android and iOS platforms using a single API.

What is Appium?

Appium is an open-source tool for automating mobile applications. It allows you to write tests using the same API for both Android and iOS, making it easier to maintain cross-platform test suites.

Setting Up Appium

Prerequisites

  1. Node.js: Install Node.js (v12 or higher)
  2. Appium Server: Install Appium via npm
  3. Android SDK: For Android testing
  4. Xcode: For iOS testing (Mac only)

Installation

npm install -g appium
npm install -g appium-doctor

Run appium-doctor to verify your setup:

appium-doctor

Writing Your First Test

Here's a simple example using WebDriverIO:

const { remote } = require('webdriverio');

const capabilities = {
  platformName: 'Android',
  platformVersion: '11.0',
  deviceName: 'Android Emulator',
  app: '/path/to/your/app.apk',
  automationName: 'UiAutomator2'
};

(async () => {
  const driver = await remote({
    hostname: 'localhost',
    port: 4723,
    path: '/',
    capabilities
  });

  const loginButton = await driver.$('~login-button');
  await loginButton.click();

  await driver.deleteSession();
})();

Best Practices

1. Use Page Object Model

Organize your tests using the Page Object Model pattern:

class LoginPage {
  constructor(driver) {
    this.driver = driver;
    this.usernameField = '~username';
    this.passwordField = '~password';
    this.loginButton = '~login';
  }

  async login(username, password) {
    await this.driver.$(this.usernameField).setValue(username);
    await this.driver.$(this.passwordField).setValue(password);
    await this.driver.$(this.loginButton).click();
  }
}

2. Use Accessibility IDs

Prefer accessibility IDs over XPath or CSS selectors for better stability:

// Good
await driver.$('~login-button').click();

// Avoid
await driver.$('//android.widget.Button[@text="Login"]').click();

3. Handle Platform Differences

Create platform-specific implementations when needed:

const isAndroid = driver.capabilities.platformName === 'Android';
const selector = isAndroid ? '~android-button' : '~ios-button';

4. Use Explicit Waits

Mobile apps can be slower to load. Use explicit waits:

await driver.waitUntil(
  async () => {
    const element = await driver.$('~content');
    return await element.isDisplayed();
  },
  {
    timeout: 10000,
    timeoutMsg: 'Content did not appear'
  }
);

Testing Strategies

1. Real Devices vs Emulators

  • Emulators/Simulators: Faster, cheaper, good for development
  • Real Devices: More accurate, necessary for final validation

2. Parallel Testing

Run tests in parallel to save time:

// Using WebDriverIO
const { multiremote } = require('webdriverio');

const capabilities = {
  device1: { /* Android capabilities */ },
  device2: { /* iOS capabilities */ }
};

3. Cloud Testing Services

Consider using cloud services like BrowserStack or Sauce Labs for:

  • Access to multiple devices
  • Parallel execution
  • CI/CD integration

Common Challenges and Solutions

Challenge 1: Flaky Tests

Solution: Use stable selectors, add proper waits, and implement retry logic.

Challenge 2: Slow Execution

Solution: Run tests in parallel, use emulators for development, real devices only for final validation.

Challenge 3: Platform-Specific Issues

Solution: Create platform-specific test suites and use conditional logic.

Conclusion

Appium is a powerful tool for mobile app testing, but it requires careful setup and best practices to be effective. By following these guidelines, you can create reliable, maintainable mobile test suites.

Need help setting up mobile test automation? Contact AstericLabs to discuss your mobile testing needs.