Appium Element Location Strategies for Mobile Automation Testing

Tool Overview for Element Detection

Appium provides several built-in tools for element identification:

  1. Appium Inspector: Built-in component for element detection
  2. UI Automator: Android SDK's native tool for element analysis

Core Concept of Element Location

Element location represents a critical component in mobile automation testing, similar to web automation. Precise element identification enables subsequent operations like input, clicks, swipes, and drag actions. Appium offers multiple location methods including ID-based, name-based, class-based, hierarchical, relative positioning, XPath, H5 element detection, and UI Automator approaches.

Available Location Methods

  • ID-based location
  • Name-based location
  • Class-based location
  • List-based location
  • Relative location
  • XPath location
  • H5 page element location
  • UI Automator location

ID-Based Element Location

Similar to unique identification numbers in real life, each UI element can have a distinct ID value for differentiation. Appium uses the find_element_by_id() method for ID-based location.

Test Scenario Example

  1. Install kaoyan3.1.0.apk
  2. Click the cancel button on upgrade screen
  3. Click skip button on guide page
from appium import webdriver

desired_caps = {}
desired_caps['platformName'] = 'Android'
desired_caps['deviceName'] = '127.0.0.1:62025'
desired_caps['platformVersion'] = '5.1.1'

desired_caps['app'] = r'C:\Users\Desktop\kaoyan3.1.0.apk'
desired_caps['appPackage'] = 'com.tal.kaoyan'
desired_caps['appActivity'] = 'com.tal.kaoyan.ui.activity.SplashActivity'

driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
driver.implicitly_wait(5)

driver.find_element_by_id('android:id/button2').click()
driver.find_element_by_id('com.tal.kaoyan:id/tv_skip').click()

Handling Conditional Elements

When dealing with optional UI elements (like update popups that may not appear), two primary approaches exist:

Approach 1 - Exception Handling

The most effective method involves catching NoSuchElementException exceptions:

from appium import webdriver
from selenium.common.exceptions import NoSuchElementException

desired_caps = {}
desired_caps['platformName'] = 'Android'
desired_caps['deviceName'] = '127.0.0.1:62025'
desired_caps['platformVersion'] = '5.1.1'
desired_caps['app'] = r'C:\Users\Desktop\kaoyan3.1.0.apk'
desired_caps['appPackage'] = 'com.tal.kaoyan'
desired_caps['appActivity'] = 'com.tal.kaoyan.ui.activity.SplashActivity'
desired_caps['noReset'] = 'True'

driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
driver.implicitly_wait(5)

def verify_cancel_button():
    try:
        cancel_element = driver.find_element_by_id('android:id/button2')
        cancel_element.click()
    except NoSuchElementException:
        print('Cancel button not found')

def verify_skip_button():
    try:
        skip_element = driver.find_element_by_id('com.tal.kaoyan:id/tv_skip')
        skip_element.click()
    except NoSuchElementException:
        print('Skip button not found')

verify_cancel_button()
verify_skip_button()

Complete Login Implementation Using ID Location

Requirements Analysis

For Chinese text input, configure these capabilities:

desired_caps['unicodeKeyboard'] = "True"
desired_caps['resetKeyboard'] = "True"

Implementation Code

from find_element.capability import driver, NoSuchElementException

def execute_login():
    driver.find_element_by_id('com.tal.kaoyan:id/login_email_edittext').clear()
    driver.find_element_by_id('com.tal.kaoyan:id/login_email_edittext').send_keys('selfstudy2018')
    
    driver.find_element_by_id('com.tal.kaoyan:id/login_password_edittext').send_keys('password2018')
    driver.find_element_by_id('com.tal.kaoyan:id/login_login_btn').click()

try:
    driver.find_element_by_id('com.tal.kaoyan:id/mainactivity_button_mysefl')
except NoSuchElementException:
    execute_login()
else:
    driver.find_element_by_id('com.tal.kaoyan:id/mainactivity_button_mysefl').click()
    driver.find_element_by_id('com.tal.kaoyan:id/activity_usercenter_username').click()
    execute_login()

Name-Based Location

For Android applications, name location corresponds to the text attribute. Usage example:

from find_element.capability import *

driver.find_element_by_name('Enter username').send_keys('selfstudy2017')
driver.find_element_by_name('Login').click()

Note: This method has been deprecated since Apppium 1.5 due to text attribute instability.

Class Name Location

Class-based location identifies elements by their type. However, many elements share identical clas names, making precise targeting challenging. For instance, both username and password fields might have the same class name: "android.widget.EditText", allowing only the first element to be targeted.

from find_element.capability import driver

driver.find_element_by_class_name('android.widget.EditText').send_keys('selfstudy2018')
driver.find_element_by_class_name('android.widget.EditText').send_keys('password2018')
driver.find_element_by_class_name('android.widget.Button').click()

Relative Location Strategy

Relative location finds a parent element with specific attributes first, then locates child elements based on that parent.

Implementation Example

from find_element.capability import driver

driver.find_element_by_id('com.tal.kaoyan:id/login_register_text').click()

parent_element = driver.find_element_by_id('com.tal.kaoyan:id/activity_register_parentlayout')
parent_element.find_element_by_class_name('android.widget.ImageView').click()

XPath Location

XPath relies on absolute or relative paths and element attributes. While absolute XPath paths have lower execution efficiency, relative paths and attribute-based selection are more practical.

XPath Exprestion Reference

Expression Description
/ Select from root node
// Select nodes regardless of position
nodename Select all child nodes
. Select current node
.. Select parent node
@ Select attributes

Practical Example

from find_element.capability import driver

driver.find_element_by_xpath('//android.widget.EditText[@text="Enter username"]').send_keys('testuser123')
driver.find_element_by_xpath('//*[@class="android.widget.EditText" and @index="3"]').send_keys('securepassword')
driver.find_element_by_xpath('//android.widget.Button').click()

List-Based Element Location

When multiple elements share the same class attribute, use list location to differentiate them:

from find_element.capability import driver

driver.find_element_by_id('com.tal.kaoyan:id/login_register_text').click()
driver.find_element_by_id('com.tal.kaoyan:id/activity_register_userheader').click()

image_list = driver.find_elements_by_id('com.tal.kaoyan:id/item_image')
image_list[10].click()

driver.find_element_by_id('com.tal.kaoyan:id/save').click()

Comprehensive Registration Implementation Using List Location

Complete Registration Flow

from find_element.capability import driver
import random

driver.find_element_by_id('com.tal.kaoyan:id/login_register_text').click()
driver.find_element_by_id('com.tal.kaoyan:id/activity_register_userheader').click()

image_collection = driver.find_elements_by_id('com.tal.kaoyan:id/item_image')
image_collection[10].click()
driver.find_element_by_id('com.tal.kaoyan:id/save').click()

# Generate unique registration data
username_value = 'user2018' + 'AUTO' + str(random.randint(1000, 9000))
password_value = 'pass' + str(random.randint(1000, 9000))
email_value = 'test' + str(random.randint(1000, 9000)) + '@gmail.com'

print('Username: %s' % username_value)
print('Password: %s' % password_value)
print('Email: %s' % email_value)

# Fill registration form
driver.find_element_by_id('com.tal.kaoyan:id/activity_register_username_edittext').send_keys(username_value)
driver.find_element_by_id('com.tal.kaoyan:id/activity_register_password_edittext').send_keys(password_value)
driver.find_element_by_id('com.tal.kaoyan:id/activity_register_email_edittext').send_keys(email_value)
driver.find_element_by_id('com.tal.kaoyan:id/activity_register_register_btn').click()

# School selection flow
driver.find_element_by_id('com.tal.kaoyan:id/perfectinfomation_edit_school_name').click()
driver.find_elements_by_id('com.tal.kaoyan:id/more_forum_title')[1].click()  # Province selection
driver.find_elements_by_id('com.tal.kaoyan:id/university_search_item_name')[1].click()  # University selection

# Major selection flow
driver.find_element_by_id('com.tal.kaoyan:id/activity_perfectinfomation_major').click()
driver.find_elements_by_id('com.tal.kaoyan:id/major_subject_title')[1].click()  # Subject
driver.find_elements_by_id('com.tal.kaoyan:id/major_group_title')[2].click()   # Group
driver.find_elements_by_id('com.tal.kaoyan:id/major_search_item_name')[1].click()  # Specific major

driver.find_element_by_id('com.tal.kaoyan:id/activity_perfectinfomation_goBtn').click()

Important: Set noReset capability to 'False' before running to avoid interference from previous registration data.

Common Error Resolution

Element Not Found Error

selenium.common.exceptions.NoSuchElementException: Message: An element could not be located on the page using the given search parameters.

Solution: Verify the accuracy of the element identifier values.

Tags: appium Mobile Testing Element Location Automation Testing xpath

Posted on Wed, 29 Jul 2026 17:03:57 +0000 by Jeroen Oosterlaar