uiautomator2 for Android UI Automation
uiautomator2 is a Python wrapper for Google's UiAutomator test framework, enabling robust UI automation for Android devices. It simplifies interacting with Android applications, performing actions like clicking, typing, scrolling, and getting device information. The current stable version is 3.5.0, with frequent patch releases addressing bug fixes and minor enhancements. It requires Python 3.8 to 3.11.
Common errors
-
uiautomator2.exceptions.GatewayError: uiautomator2 server not started
cause The `atx-agent` server, which enables communication between the Python client and the Android device, is not running on the device.fixRun `python -m uiautomator2 init` (or `u2 init`) in your terminal. Ensure your device is connected via ADB and has granted debugging permissions. This command will install and start the necessary server. -
AdbError: device not found
cause The Android Debug Bridge (ADB) cannot detect your device. This could be due to a disconnected cable, unauthorized device, missing ADB drivers, or an incorrect IP address/serial for wireless connection.fix1. Ensure the device is physically connected (if using USB). 2. Verify 'USB debugging' is enabled in Developer Options. 3. Check for 'Allow USB debugging?' prompt on the device and accept it. 4. Run `adb devices` in your terminal to confirm the device is listed. 5. If connecting wirelessly, ensure the IP address is correct and ADB is connected (`adb connect <ip>`). -
No module named 'uiautomator2'
cause The `uiautomator2` Python package is not installed in your current Python environment.fixInstall the package using pip: `pip install uiautomator2`. -
AttributeError: 'UiObject' object has no attribute 'scroll_to_end'
cause Methods like `scroll_to_end` or `fling_to_end` are typically available only on UiObjects that are recognized as scrollable containers. Calling them on a generic or non-scrollable UiObject will raise an error.fixEnsure the `UiObject` you're targeting is indeed a scrollable element (e.g., a RecyclerView or ScrollView). If not, you might need to find its parent scrollable container or use general device-level scrolling methods like `d.scroll()` or `d.swipe()`.
Warnings
- gotcha The `uiautomator2` server (atx-agent) must be installed and running on the Android device for the Python client to connect. Forgetting to initialize often leads to connection errors.
- breaking uiautomator2 has a tight dependency on specific versions of `adbutils`. Upgrading `adbutils` independently of `uiautomator2` might lead to compatibility issues or unexpected behavior, as breaking changes in `adbutils` are often addressed in subsequent `uiautomator2` releases.
- gotcha As of version 3.5.0, `d.send_keys()` automatically hides the input method after text entry. If your script previously included an explicit `d.hide_keyboard()` call immediately after `send_keys`, this might result in an unnecessary or problematic extra action.
- gotcha Element locators (e.g., XPath, text, resourceId) can be brittle. XPath is often slow and prone to breaking with minor UI changes. Text-based selectors can fail with localization or dynamic content. `resourceId` is generally the most stable if available and unique.
Install
-
pip install uiautomator2
Imports
- uiautomator2
from uiautomator2 import connect
import uiautomator2 as u2
Quickstart
import uiautomator2 as u2
import os
# Connect to a device. You can specify a serial (e.g., 'emulator-5554')
# or an IP address (e.g., '192.168.1.100'). If no argument is given,
# it tries to connect to the first available device via ADB.
# Ensure 'adb devices' shows your device and 'u2 init' has been run on the device.
# Example for connecting to a specific IP, fallback to default
DEVICE_ADDRESS = os.environ.get('U2_DEVICE_ADDRESS', None)
try:
if DEVICE_ADDRESS:
d = u2.connect(DEVICE_ADDRESS)
else:
d = u2.connect() # Connects to the default/first available device
print(f"Successfully connected to device: {d.info.get('serial', 'N/A')}")
# Print basic device information
print("Device Info:", d.info)
# Get the current package and activity
current_app = d.app_current()
print(f"Current app: {current_app['package']} / {current_app['activity']}")
# Take a screenshot and save it
screenshot_path = "uiautomator2_quickstart_screenshot.png"
d.screenshot(screenshot_path)
print(f"Screenshot saved to {screenshot_path}")
# Interact with the UI (example: press the Home button)
d.press("home")
print("Pressed Home button.")
# Dump the current UI hierarchy (useful for inspecting elements)
xml_dump = d.dump_hierarchy()
print("UI Hierarchy (first 200 characters):", xml_dump[:200])
except Exception as e:
print(f"An error occurred: {e}")
print("\nTroubleshooting steps:")
print("1. Ensure your Android device is connected via USB/WiFi and ADB debugging is enabled.")
print("2. Run 'adb devices' in your terminal to confirm ADB detects your device.")
print("3. Run 'python -m uiautomator2 init' (or 'u2 init') to install the uiautomator2 server on the device.")
print("4. If connecting via IP, ensure the device is on the same network and you're using the correct IP.")