Salta ai contenuti

Appium Cheat Sheet

Overview

Appium is an open-source test automation framework for native, hybrid, and mobile web applications. It uses the WebDriver protocol (W3C standard) to drive iOS, Android, and Windows apps, allowing testers to write tests in any language that has a WebDriver client library — including Java, Python, JavaScript, Ruby, C#, and more. Appium follows a philosophy of not requiring app modifications for testing; it tests the same app binary that goes to production.

Appium 2.x introduces a driver/plugin architecture where platform support is installed as separate drivers (XCUITest for iOS, UiAutomator2 for Android, Windows for desktop). It supports real devices and emulators/simulators, provides element inspection tools, handles gestures and multi-touch interactions, and integrates with CI/CD pipelines. Appium can also test Flutter apps, React Native apps, and Espresso-based tests through specialized drivers.

Installation

# Prerequisites: Node.js 16+ and npm
node --version
npm --version

# Install Appium 2.x
npm install -g appium

# Install drivers
appium driver install uiautomator2    # Android
appium driver install xcuitest        # iOS
appium driver install mac2            # macOS
appium driver install windows         # Windows

# Verify installation
appium --version
appium driver list --installed

# Install Appium Doctor (checks prerequisites)
npm install -g @appium/doctor
appium-doctor --android
appium-doctor --ios

# Android prerequisites
# - Java JDK 11+
# - Android SDK (via Android Studio)
# - ANDROID_HOME environment variable
# - Platform tools in PATH
export ANDROID_HOME=$HOME/Android/Sdk
export PATH=$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools/bin

# iOS prerequisites (macOS only)
# - Xcode with command line tools
# - Carthage: brew install carthage
xcode-select --install
brew install carthage

# Install Appium Inspector (GUI element inspector)
# Download from https://github.com/appium/appium-inspector/releases

# Start Appium server
appium
appium --port 4723 --log-level info
appium --allow-cors  # For Appium Inspector

Desired Capabilities

# Android capabilities
android_caps = {
    "platformName": "Android",
    "appium:automationName": "UiAutomator2",
    "appium:deviceName": "Pixel_7_API_34",
    "appium:app": "/path/to/app.apk",
    "appium:appPackage": "com.example.myapp",
    "appium:appActivity": "com.example.myapp.MainActivity",
    "appium:noReset": True,
    "appium:fullReset": False,
    "appium:newCommandTimeout": 300,
    "appium:autoGrantPermissions": True,
}

# iOS capabilities
ios_caps = {
    "platformName": "iOS",
    "appium:automationName": "XCUITest",
    "appium:deviceName": "iPhone 15 Pro",
    "appium:platformVersion": "17.4",
    "appium:app": "/path/to/app.ipa",
    "appium:bundleId": "com.example.myapp",
    "appium:noReset": True,
    "appium:xcodeOrgId": "TEAM_ID",
    "appium:xcodeSigningId": "iPhone Developer",
    "appium:udid": "auto",
}

# Mobile web capabilities
web_caps = {
    "platformName": "Android",
    "appium:automationName": "UiAutomator2",
    "appium:deviceName": "emulator-5554",
    "browserName": "Chrome",
}

Python Client Setup

# Install client
# pip install Appium-Python-Client

from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.options.ios import XCUITestOptions
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# Connect to Appium server
options = UiAutomator2Options()
options.platform_name = "Android"
options.device_name = "emulator-5554"
options.app = "/path/to/app.apk"

driver = webdriver.Remote(
    command_executor="http://127.0.0.1:4723",
    options=options
)

# Basic operations
driver.find_element(AppiumBy.ID, "com.example:id/username").send_keys("testuser")
driver.find_element(AppiumBy.ID, "com.example:id/password").send_keys("pass123")
driver.find_element(AppiumBy.ID, "com.example:id/login_btn").click()

# Wait for element
wait = WebDriverWait(driver, 10)
element = wait.until(
    EC.presence_of_element_located((AppiumBy.ACCESSIBILITY_ID, "Welcome"))
)

# Cleanup
driver.quit()

Element Locator Strategies

StrategyPython UsageDescription
IDAppiumBy.ID, "resource-id"Android resource ID
Accessibility IDAppiumBy.ACCESSIBILITY_ID, "label"Content description / accessibility label
XPathAppiumBy.XPATH, "//android.widget.Button"XPath expression
Class NameAppiumBy.CLASS_NAME, "android.widget.TextView"UI class name
Android UIAutomatorAppiumBy.ANDROID_UIAUTOMATOR, 'new UiSelector()...'Android UIAutomator selector
iOS Class ChainAppiumBy.IOS_CLASS_CHAIN, "**/XCUIElementTypeButton"iOS class chain
iOS PredicateAppiumBy.IOS_PREDICATE, "label == 'Login'"iOS predicate string
# Android UIAutomator selectors
driver.find_element(
    AppiumBy.ANDROID_UIAUTOMATOR,
    'new UiSelector().text("Login")'
)
driver.find_element(
    AppiumBy.ANDROID_UIAUTOMATOR,
    'new UiSelector().resourceId("com.example:id/btn").enabled(true)'
)
driver.find_element(
    AppiumBy.ANDROID_UIAUTOMATOR,
    'new UiScrollable(new UiSelector().scrollable(true)).scrollIntoView('
    'new UiSelector().text("Target Item"))'
)

# iOS predicate string
driver.find_element(
    AppiumBy.IOS_PREDICATE,
    'type == "XCUIElementTypeButton" AND label CONTAINS "Submit"'
)

# iOS class chain
driver.find_element(
    AppiumBy.IOS_CLASS_CHAIN,
    '**/XCUIElementTypeCell[`name CONTAINS "item"`]'
)

Gestures and Actions

from appium.webdriver.common.touch_action import TouchAction
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.actions import interaction
from selenium.webdriver.common.actions.pointer_input import PointerInput

# Tap
element = driver.find_element(AppiumBy.ID, "button")
element.click()

# Long press (W3C Actions)
actions = ActionChains(driver)
actions.click_and_hold(element).pause(2).release().perform()

# Swipe using W3C Actions
def swipe(driver, start_x, start_y, end_x, end_y, duration=800):
    pointer = PointerInput(interaction.POINTER_TOUCH, "finger")
    actions = ActionChains(driver)
    actions.w3c_actions.devices.append(pointer)
    actions.w3c_actions.pointer_action.move_to_location(start_x, start_y)
    actions.w3c_actions.pointer_action.pointer_down()
    actions.w3c_actions.pointer_action.pause(duration / 1000)
    actions.w3c_actions.pointer_action.move_to_location(end_x, end_y)
    actions.w3c_actions.pointer_action.pointer_up()
    actions.perform()

# Swipe up
size = driver.get_window_size()
swipe(driver, size['width']//2, size['height']*3//4,
      size['width']//2, size['height']//4)

# Scroll to element (Android)
driver.find_element(
    AppiumBy.ANDROID_UIAUTOMATOR,
    'new UiScrollable(new UiSelector().scrollable(true))'
    '.scrollIntoView(new UiSelector().text("Target"))'
)

# Pinch and zoom (multi-touch)
# Use mobile: commands
driver.execute_script('mobile: pinchOpen', {
    'elementId': element.id,
    'percent': 0.75,
    'speed': 2500
})

App Management

# App lifecycle
driver.install_app("/path/to/app.apk")
driver.remove_app("com.example.myapp")
driver.activate_app("com.example.myapp")
driver.terminate_app("com.example.myapp")
is_installed = driver.is_app_installed("com.example.myapp")
driver.background_app(5)  # Background for 5 seconds

# Context switching (hybrid apps)
contexts = driver.contexts
print(contexts)  # ['NATIVE_APP', 'WEBVIEW_com.example']
driver.switch_to.context('WEBVIEW_com.example')
# Now use web selectors
driver.find_element(AppiumBy.CSS_SELECTOR, "#login-form")
driver.switch_to.context('NATIVE_APP')

# Screenshots
driver.save_screenshot("screenshot.png")
element.screenshot("element.png")

# Device actions
driver.orientation = "LANDSCAPE"
driver.orientation = "PORTRAIT"
driver.open_notifications()  # Android
driver.press_keycode(4)  # Android back button
driver.hide_keyboard()
driver.lock()
driver.unlock()

Configuration

// .appiumrc.json (Appium server config)
{
  "server": {
    "port": 4723,
    "host": "0.0.0.0",
    "log-level": "info",
    "log": "appium.log",
    "allow-cors": true,
    "keep-alive-timeout": 600
  }
}
# pytest conftest.py
import pytest
from appium import webdriver
from appium.options.android import UiAutomator2Options

@pytest.fixture(scope="session")
def driver():
    options = UiAutomator2Options()
    options.platform_name = "Android"
    options.device_name = "emulator-5554"
    options.app = "path/to/app.apk"
    options.no_reset = True
    
    driver = webdriver.Remote("http://127.0.0.1:4723", options=options)
    driver.implicitly_wait(10)
    yield driver
    driver.quit()

Advanced Usage

# Page Object pattern
class LoginPage:
    def __init__(self, driver):
        self.driver = driver
    
    @property
    def username_field(self):
        return self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "username")
    
    @property
    def password_field(self):
        return self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "password")
    
    @property
    def login_button(self):
        return self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "loginButton")
    
    def login(self, username, password):
        self.username_field.send_keys(username)
        self.password_field.send_keys(password)
        self.login_button.click()
        return HomePage(self.driver)

# Parallel execution with pytest-xdist
# conftest.py
def get_device(worker_id):
    devices = {
        "gw0": {"udid": "emulator-5554", "port": 4723},
        "gw1": {"udid": "emulator-5556", "port": 4725},
    }
    return devices.get(worker_id, devices["gw0"])

# Run: pytest -n 2 tests/

Troubleshooting

IssueSolution
”Could not find adb”Set ANDROID_HOME; ensure platform-tools in PATH
Session creation failsCheck Appium server running; verify capabilities match device
Element not foundUse Appium Inspector to verify locator; add explicit wait
iOS real device failsConfigure code signing; set xcodeOrgId and xcodeSigningId
App not installingCheck APK/IPA path; verify device storage space
Timeout errorsIncrease newCommandTimeout; use explicit waits
WebView context missingEnable WebView debugging in app; check chromedriverExecutable
Emulator not startingStart emulator manually first; check AVD configuration
Gestures not workingUse W3C Actions API; check coordinates are within screen bounds
Parallel tests conflictUse different ports and device UDIDs for each session