Toolkit for testing Android applications using Appium with Espresso driver. Supports automated UI testing, gesture interactions, element discovery, and screenshot capture. Use when testing native Android apps (.apk files), verifying mobile UI functionality, automating gestures (swipe, scroll, tap), or running blackbox tests on Android devices/emulators.
To test Android applications, write Python scripts using Appium with the Espresso driver for fast, reliable automation.
Key Advantage: Espresso driver is 2x faster than UI Automator 2 with automatic UI synchronization - no manual waits needed.
Helper Scripts Available:
scripts/check_setup.py - Verifies Appium server, drivers, and device connectivityAlways run scripts with --help first to see usage. These scripts handle common setup tasks without cluttering your context window.
User task → Do you have app source code?
├─ Yes → Use Espresso driver (FAST, automatic waits)
│ 1. Start Appium server: appium
│ 2. Write test with Espresso automation
│ 3. Reference examples/ for patterns
│
└─ No (black-box testing) → Use UI Automator 2 driver
1. Start Appium server: appium
2. Write test with UiAutomator2 automation
3. Expect slower execution, add explicit waits
Recommendation: Use Espresso driver whenever possible (requires app source code but much faster).
Run the setup checker first:
python scripts/check_setup.py
This verifies:
from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.webdriver.common.appiumby import AppiumBy
# Configure for Espresso (fast!)
options = UiAutomator2Options()
options.platform_name = "Android"
options.automation_name = "Espresso" # Use Espresso for speed
options.app = "/path/to/app.apk"
options.device_name = "Android Emulator"
options.auto_grant_permissions = True
# Start session
driver = webdriver.Remote("http://localhost:4723", options=options)
# Espresso automatically waits - just find and interact
driver.find_element(by=AppiumBy.ID, value="username").send_keys("testuser")
driver.find_element(by=AppiumBy.ID, value="login_button").click()
# Verify result
assert driver.find_element(by=AppiumBy.ID, value="home_screen").is_displayed()
driver.quit()
For detailed guidance, see the project's comprehensive testing docs:
Location: docs/research/android_testing/
Files:
README.md - Setup, installation, prerequisites, and key differencescommon_actions.py - Reusable action library - Copy these instead of rewriting!example_tests.py - Full test scenarios (login, lists, forms, gestures, navigation)ai_agent_guide.md - Specific guidance for QA agents in multi-agent teamsWhen to read:
README.mdcommon_actions.py, reference example_tests.pyai_agent_guide.mdThe examples/ directory contains practical patterns:
login_test.py - Login flow with success/failure caseslist_scroll.py - Scrolling through lists and selecting itemsgesture_test.py - Swipe, long press, and other gestureselement_discovery.py - Finding buttons, inputs, and text on screenPattern: Copy an example closest to your test case, then modify.
Use Espresso driver when possible (2x faster, automatic waits):
options.automation_name = "Espresso" # FAST ✅
Prefer ID locators (fastest):
driver.find_element(by=AppiumBy.ID, value="button_login") # FAST ✅
Copy patterns from common_actions.py instead of rewriting:
from common_actions import tap_element, input_text
Let Espresso handle waits (no manual time.sleep() needed)
Take screenshots on failures for debugging:
driver.save_screenshot("/tmp/test_failure.png")
Don't use XPath unless absolutely necessary (very slow):
# AVOID ❌
driver.find_element(by=AppiumBy.XPATH, value="//button[@text='Login']")
# PREFER ✅
driver.find_element(by=AppiumBy.ID, value="login_button")
Don't use TouchAction class (removed in Appium 2.0+):
# WRONG ❌ (Appium 1.x)
from appium.webdriver.common.touch_action import TouchAction
# CORRECT ✅ (Appium 2.0+)
driver.execute_script('mobile: clickGesture', {'x': 100, 'y': 200})
Don't add explicit waits with Espresso (automatic waits built-in)
Don't forget cleanup (always close session in finally block)
❌ Don't start tests before Appium server is running
✅ Do start Appium server first: appium
❌ Don't forget to install Espresso driver
✅ Do install driver: appium driver install espresso
❌ Don't test before device is connected
✅ Do check device: adb devices
When testing unfamiliar apps:
Launch and wait:
driver.find_element(by=AppiumBy.ID, value="com.app:id/main")
time.sleep(2) # Let app fully load
Take screenshot:
driver.save_screenshot('/tmp/screen.png')
Discover elements:
# List all buttons
buttons = driver.find_elements(by=AppiumBy.CLASS_NAME, value="android.widget.Button")
for btn in buttons:
print(f"Button: {btn.text} (ID: {btn.get_attribute('resource-id')})")
Identify IDs from output and use in tests
See examples/element_discovery.py for complete pattern.
For QA agents in multi-agent workflows, see ai_agent_guide.md in comprehensive docs for:
sync Appium client (not async)finally blockSee docs/research/android_testing/ for:
Based on 2026-01-06 Android automation research: