Developing E2E tests for a mobile application (Appium)

NOVASOLUTIONS.TECHNOLOGY is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
Developing E2E tests for a mobile application (Appium)
Complex
~5 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1050
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Developing E2E Tests for Mobile Applications (Appium)

Appium is the only tool in mobile testing that covers iOS and Android with one test code. That's its main advantage and simultaneously the source of most problems. Behind universality lies an abstraction layer that sometimes behaves unpredictably. Writing stable Appium tests is harder than it appears.

Architecture: Appium 2 vs Appium 1

Appium 2 is not just a version, it's a different concept. Instead of monolithic server — core plus separately installed drivers:

npm install -g appium@next
appium driver install uiautomator2   # Android
appium driver install xcuitest       # iOS

UIAutomator2Driver for Android, XCUITestDriver for iOS. Both support W3C WebDriver Protocol, making them compatible with WebdriverIO, Selenium Grid, and standard client libraries.

Versions we work with in 2024–2025:

  • Appium 2.5+
  • appium-uiautomator2-driver 3.x
  • appium-xcuitest-driver 7.x
  • WebdriverIO 8.x (JS/TS) or Appium-Python-Client 4.x (Python)

Server Setup and Capabilities

The most painful place — proper Capabilities set. Wrong platformVersion or missing automationName — and session doesn't start with uninformative error.

Minimal working config for Android (WebdriverIO):

const capabilities = {
  platformName: 'Android',
  'appium:automationName': 'UiAutomator2',
  'appium:deviceName': 'emulator-5554',
  'appium:app': path.resolve('./apps/myapp.apk'),
  'appium:newCommandTimeout': 240,
  'appium:noReset': false,
};

For iOS add udid of device, xcodeOrgId and xcodeSigningId for real device. On simulator easier — but simulator doesn't give performance results and Push Notifications.

Page Object and Test Structure

Raw Appium code without pattern — nightmare for maintenance. Each $('//XCUIElementTypeButton[@name="Login"]') duplicates in dozens of tests, and when UI changes you fix everything at once.

Page Object with WebdriverIO:

class LoginPage {
  get emailField() { return $('~email_input'); } // accessibilityId
  get passwordField() { return $('~password_input'); }
  get submitButton() { return $('~login_button'); }

  async login(email: string, password: string) {
    await this.emailField.setValue(email);
    await this.passwordField.setValue(password);
    await this.submitButton.click();
  }
}

export default new LoginPage();

~ prefix is accessibilityId locator. Works on iOS (accessibilityIdentifier) and Android (contentDescription). Prefer it over XPath — more stable when view hierarchy changes.

Use XPath only when no alternatives: //android.widget.TextView[contains(@text,'Add')]. But long XPath chains — first cause of unstable tests.

Waits Instead of Sleep

driver.pause(3000) — anti-pattern. Replace with explicit waits:

await $('~submit_btn').waitForDisplayed({ timeout: 10000 });
await $('~success_screen').waitForExist({ timeout: 15000 });

waitForDisplayed waits for element in visible area. waitForExist — just existing in DOM. For elements appearing after animation — waitForDisplayed with { timeout: 5000, interval: 500 }.

CI Integration

Appium in CI requires running emulator or connected device. Typical scheme for GitHub Actions:

- name: Start Android Emulator
  uses: reactivecircus/android-emulator-runner@v2
  with:
    api-level: 34
    target: google_apis
    arch: x86_64
    script: |
      appium &
      sleep 5
      npx wdio run wdio.conf.ts

For iOS in CI need macOS runner. Use actions/runner on macOS with Xcode pre-installed. Create simulator through xcrun simctl create.

Alternative — cloud device farms: Firebase Test Lab, BrowserStack App Automate, Sauce Labs. There emulator/device and Appium server are provided by platform.

Common Issues

StaleElementReferenceError — found element, but UI restructured before click. Wrap in retry logic: await browser.waitUntil(async () => { ... }).

Keyboard covers element — on iOS screen keyboard covers field. Before text input — await driver.hideKeyboard() or scroll to element: await element.scrollIntoView().

App doesn't respond to commands after background'appium:forceAppLaunch': true in capabilities or explicit driver.activateApp(bundleId).

Different locators on iOS and Android — even with accessibilityId sometimes need platform-specific locators. Solve through condition:

const selector = driver.isIOS ? '~ios_id' : '~android_id';

What's Included

  • Setting up Appium 2 server and drivers for iOS and Android
  • Writing tests (WebdriverIO/TypeScript or Python)
  • Page Object pattern for all key screens
  • CI integration (GitHub Actions / GitLab CI)
  • Cloud farm execution setup on demand
  • Allure or HTML reports with screenshots for each step

Timeline

5 days — basic configuration + coverage of 3–5 key flows. Full E2E coverage of large application (15–20 scenarios) — 2–3 weeks. Cost is calculated individually after app and infrastructure analysis.