Appium is a cross-platform framework for automating testing of mobile, web and desktop applications, based on the WebDriver protocol. It allows you to write tests in any programming language and run them on Android, iOS and Windows without changing code. According to the Appium Foundation, 2025, the WebDriver protocol provides a unified interface for interacting with applications on different platforms.
Key Takeaways
Appium is an open-source framework for automating mobile application testing, built on a client-server architecture. The Appium server receives commands from the client via the WebDriver protocol and delegates them to native drivers: XCUITest for iOS, UiAutomator2 for Android, and WinAppDriver for Windows.
Appium was created in 2013 and has since become the industry standard for cross-platform testing. The project is managed by the Appium Foundation and supported by major companies: Sauce Labs, HeadSpin, Microsoft. Appium is used by over 500 thousand testers worldwide every month.
Appium supports three types of applications: native (iOS, Android, Windows), mobile web browsers (Safari, Chrome), and hybrid applications (WebView inside a native shell). Each type uses its own context: NATIVE_APP, WEBVIEW, or CHROMIUM.
The Appium architecture consists of four layers: client code → Appium Client Library → Appium Server → native driver. The client library implements the WebDriver protocol and sends HTTP requests to the server. The server converts them into native driver commands for the platform.
WebDriver is a W3C standard for browser automation, adapted by Appium for mobile devices. Each action — element search, tap, text input — is sent as an HTTP request to the server. For example, POST /session/{id}/element creates a new testing session.
Each test begins by creating a session through the Desired Capabilities object. It specifies: platformName, deviceName, appPath, automationName, and additional parameters. Appium uses this data to select the appropriate native driver and device configuration.
# Desired Capabilities Example for Android
desired_caps = {
'platformName': 'Android',
'deviceName': 'Pixel_4',
'app': '/path/to/app.apk',
'automationName': 'UiAutomator2',
'appPackage': 'com.example.app',
'appActivity': '.MainActivity'
}
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
Appium is installed via npm: npm install -g appium. After installation, you need to configure native drivers for each platform: appium driver install xcuitest and appium driver install uiautomator2. Xcode is required for iOS and Android SDK for Android.
Appium Inspector is a graphical tool for inspecting UI elements. It connects to a running Appium server and shows the hierarchy of UI components, their attributes, and locators. Inspector allows you to verify a selector before writing a test.
The Appium server is started with the appium command with optional parameters: port, address, logging. By default, the server listens on port 4723. Different ports or Appium clusters are used for parallel execution on multiple devices.
# Starting Appium Server with Logging
appium \
--port 4723 \
--log-level debug \
--use-plugins images \
--base-path /wd/hub
Appium tests use the Page Object pattern for code organization. Each app screen is described by a separate class with element locators and interaction methods. Page Object Model simplifies test maintenance when the interface changes and reuses selectors between test scenarios.
Appium supports many element search strategies: id, xpath, accessibilityId, className, androidUIAutomator, and iOSClassChain. The most preferred are accessibilityId and id — they are stable despite layout changes. XPath should only be used when other locators are not available.
// Page Object for Login Screen
public class LoginPage {
private AppiumDriver driver;
private MobileElement emailField =
(MobileElement) driver.findElement(MobileBy.AccessibilityId("emailInput"));
private MobileElement passwordField =
(MobileElement) driver.findElement(MobileBy.AccessibilityId("passwordInput"));
private MobileElement loginButton =
(MobileElement) driver.findElement(MobileBy.AccessibilityId("loginButton"));
public void login(String email, String password) {
emailField.sendKeys(email);
passwordField.sendKeys(password);
loginButton.click();
}
}
Appium supports complex gestures through the TouchAction class or W3C Actions API: swipes, multi-touch, long presses, scroll to element. The new W3C Actions API is recommended for new projects as it is standardized and works more stably across different platform versions.
Appium is often compared with Detox, XCUITest, and Espresso. Appium's main advantage is cross-platform capability: one test can run on iOS and Android without changes. However, Detox provides better synchronization for React Native, and XCUITest/Espresso offer faster execution for native tests.
Appium is suitable for projects that require a single framework for iOS, Android, and web. It is indispensable in teams with testers who write in Java or Python. For React Native projects with many E2E tests, consider Detox due to automatic synchronization.
| Framework | Approach | Speed | Cross-platform |
|---|---|---|---|
| Appium | Black-box | Medium | iOS, Android, Windows |
| Detox | Gray-box | High | iOS + Android (React Native) |
| XCUITest | White-box | High | iOS Only |
Appium Grid is an extension for running tests in parallel on multiple devices simultaneously. Appium Grid is built on Selenium Grid and allows distributing tests across multiple Appium servers, each managing its own set of devices or emulators. This is critical for large projects where regression testing on a single device takes hours — Grid reduces the time to minutes proportional to the number of nodes.
Grid configuration uses a JSON configuration file describing nodes with devices. Each node specifies: server port, list of devices with platform, OS version, and maximum number of sessions. The Hub distributes tests across free nodes, ensuring maximum infrastructure utilization.
{
"capabilities": [
{
"browserName": "android",
"platformName": "Android",
"deviceName": "Pixel_4",
"platformVersion": "14.0",
"maxInstances": 2
}
],
"configuration": {
"port": 4724,
"registerCycle": 5000
}
}
If your own device infrastructure is not available, there are cloud services: Sauce Labs, BrowserStack, LambdaTest. They provide hundreds of real devices and emulators in the cloud. Integration with Appium is minimal: just specify the cloud hub URL and credentials in Desired Capabilities instead of localhost.
Appium supports parallel test execution using TestNG (Java) or pytest-xdist (Python). Parallelization requires unique ports for each session and isolated test data. Each thread starts its own Appium session on a separate device or emulator. When using cloud services, parallelization is automatic — the platform distributes tests across available devices and releases them after completion.
When encountering problems with Appium, the first step is to check the server log (appium --log-level debug). Typical errors: port is busy (specify another --port), incompatible driver version, missing Android SDK or Xcode. For iOS, ensure that WebKitAgent is running and has access to the simulator.
If Appium cannot find an element, check: is the correct context set (NATIVE_APP vs WEBVIEW), is the element visible on screen, does it require scrolling, and is the locator correct. Use Appium Inspector for interactive searching and checking XPath expressions before inserting them into the test. It is also helpful to enable waiting for element visibility through WebDriverWait — this solves synchronization issues with slow UI loading.
Improper session termination is a common cause of Appium test instability. Always close the driver in a finally block or via AutoCloseable. In case of failures, use driver.quit() forcefully. For iOS, ensure that WebKitAgent (WDA) restarts between sessions, otherwise a session not created error may occur. For monitoring session status in CI, it is convenient to connect the Appium Dashboard plugin, which visualizes the status of all running tests in real time.
To improve test stability, use: shouldTerminateApp (terminate app between tests), noReset (preserve data between sessions), autoGrantPermissions (auto-allow system dialogs). It is also recommended to disable animations on the device through Developer Options.
Frequently Asked Questions
Appium supports all popular languages through client libraries: Java, Python, JavaScript, Ruby, C#, PHP, and Kotlin. Each library implements the same WebDriver protocol, allowing you to write cross-platform tests in any language.
No, Appium works with both real devices and emulators and simulators. For Android, Android Studio emulators are used; for iOS, Xcode simulators. Real devices are only necessary for testing hardware functions: sensors, NFC, camera.
Appium 2 has been completely rewritten with a modular architecture featuring plugins and separate drivers. In Appium 1, all drivers were built into the server. Appium 2 uses appium driver install commands to install drivers and appium plugin install for plugins.
Appium uses search strategies: By.id, By.xpath, By.accessibilityId, By.className, By.androidUIAutomator, and By.iOSClassChain. For speed, it is recommended to use accessibilityId — it is stable and does not depend on layout changes.
Yes, Appium supports testing mobile browsers — Safari on iOS and Chrome on Android. This uses the WEBVIEW or CHROMIUM context. Tests run in the browser through standard WebDriver, similar to Selenium.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also