加菲猫欢乐跑
65.99M · 2026-03-26
本文将全面介绍如何使用Python+Appium进行移动端自动化测试,重点解决元素定位和手势操作中的常见痛点问题,并提供详细的源码示例。
要开始Appium自动化测试,首先需要搭建好运行环境:
npm install -g appium)pip install Appium-Python-Client)连接真机或模拟器后,需要进行初始化配置:
from appium import webdriver
import time
desired_caps = {
'platformName': 'Android', # 平台名称
'platformVersion': '10', # 平台版本
'deviceName': 'your_device_name', # 设备名称
'appPackage': 'com.example.app', # 被测App包名
'appActivity': 'com.example.app.MainActivity', # 启动Activity
'noReset': True, # 不重置应用状态
'automationName': 'UiAutomator2' # 自动化引擎
}
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
time.sleep(5) # 等待应用启动
Appium提供了多种元素定位方式,以下是6种最常用的方法:
ID定位:通过resource-id属性定位
driver.find_element_by_id("com.example.app:id/btn_login").click()
Class Name定位:通过控件类名定位
driver.find_element_by_class_name("android.widget.Button").click()
XPath定位:通过XPath表达式定位
driver.find_element_by_xpath('//android.widget.Button[@text="登录"]').click()
Accessibility ID(content-desc)定位:通过content-desc属性定位
driver.find_element_by_accessibility_id("搜索按钮").click()
UIAutomator定位:使用Android UIAutomator API定位
driver.find_element_by_android_uiautomator('new UiSelector().text("确定")').click()
组合定位:结合多种属性定位
driver.find_element_by_xpath('//android.widget.Button[contains(@text,"登")]').click()
痛点1:动态ID问题
有些元素的ID是动态生成的,每次运行都会变化。解决方案:
# 使用contains函数匹配部分文本
driver.find_element_by_xpath('//*[contains(@resource-id,"btn_")]').click()
痛点2:列表元素定位
对于列表中的相似元素,可以通过索引或特定属性定位:
# 通过索引定位列表中的第三个元素
elements = driver.find_elements_by_class_name("android.widget.TextView")
elements[2].click()
# 或者使用UIAutomator的childSelector
driver.find_element_by_android_uiautomator(
'new UiSelector().className("android.widget.ListView")'
'.childSelector(new UiSelector().text("Item 3"))'
).click()
痛点3:等待元素出现
使用显式等待解决元素加载延迟问题:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "com.example.app:id/btn_submit"))
)
element.click()
from appium.webdriver.common.touch_action import TouchAction
# 简单点击
driver.tap([(x, y)], duration=100)
# 长按操作
element = driver.find_element_by_id("com.example.app:id/btn_hold")
TouchAction(driver).long_press(element).perform()
# 从(x1,y1)滑动到(x2,y2)
driver.swipe(start_x=100, start_y=500, end_x=100, end_y=100, duration=800)
# 元素拖动
source = driver.find_element_by_id("com.example.app:id/drag_source")
target = driver.find_element_by_id("com.example.app:id/drop_target")
TouchAction(driver).press(source).move_to(target).release().perform()
from appium.webdriver.common.multi_action import MultiAction
from appium.webdriver.common.touch_action import TouchAction
# 创建两个触摸动作
action1 = TouchAction(driver).press(x=100, y=100).move_to(x=100, y=400).release()
action2 = TouchAction(driver).press(x=200, y=100).move_to(x=200, y=400).release()
# 执行多点触控
multi_action = MultiAction(driver)
multi_action.add(action1, action2)
multi_action.perform()
# 定义九宫格坐标点
points = {
1: (100, 300),
2: (300, 300),
3: (500, 300),
4: (100, 500),
5: (300, 500),
6: (500, 500),
7: (100, 700),
8: (300, 700),
9: (500, 700)
}
# 执行解锁手势(例如1->2->3->6->9)
pattern = [1, 2, 3, 6, 9]
action = TouchAction(driver)
action.press(**points[pattern[0]])
for num in pattern[1:]:
action.move_to(**points[num]).wait(100)
action.release().perform()
# 双指放大
action1 = TouchAction(driver).press(x=200, y=300).move_to(x=100, y=200).release()
action2 = TouchAction(driver).press(x=400, y=300).move_to(x=500, y=200).release()
multi_action = MultiAction(driver)
multi_action.add(action1, action2)
multi_action.perform()
# 双指缩小(反向操作)
action1 = TouchAction(driver).press(x=100, y=200).move_to(x=200, y=300).release()
action2 = TouchAction(driver).press(x=500, y=200).move_to(x=400, y=300).release()
multi_action = MultiAction(driver)
multi_action.add(action1, action2)
multi_action.perform()
下面是一个完整的自动化测试示例,模拟用户登录、浏览和退出应用的过程:
from appium import webdriver
from appium.webdriver.common.touch_action import TouchAction
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
# 初始化配置
desired_caps = {
'platformName': 'Android',
'platformVersion': '10',
'deviceName': 'emulator-5554',
'appPackage': 'com.example.app',
'appActivity': 'com.example.app.MainActivity',
'noReset': True,
'automationName': 'UiAutomator2'
}
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
wait = WebDriverWait(driver, 15)
try:
# 1. 等待并点击登录按钮
login_btn = wait.until(
EC.element_to_be_clickable((By.ID, "com.example.app:id/btn_login"))
)
login_btn.click()
# 2. 输入用户名和密码
username = wait.until(
EC.presence_of_element_located((By.ID, "com.example.app:id/et_username"))
)
username.send_keys("testuser")
password = driver.find_element_by_id("com.example.app:id/et_password")
password.send_keys("password123")
# 3. 点击登录提交按钮
submit_btn = driver.find_element_by_id("com.example.app:id/btn_submit")
submit_btn.click()
# 4. 等待登录成功,滑动浏览内容
time.sleep(3) # 等待登录完成
for _ in range(2):
driver.swipe(start_x=500, start_y=1500, end_x=500, end_y=500, duration=800)
time.sleep(1)
# 5. 长按某个项目
item = driver.find_element_by_xpath('//android.widget.TextView[@text="特别推荐"]')
TouchAction(driver).long_press(item).perform()
# 6. 点击弹出菜单中的选项
menu_option = wait.until(
EC.element_to_be_clickable((By.XPATH, '//android.widget.TextView[@text="收藏"]'))
)
menu_option.click()
# 7. 返回主页
driver.back()
# 8. 打开侧边栏
driver.swipe(start_x=50, start_y=800, end_x=600, end_y=800, duration=500)
# 9. 点击退出登录
logout_btn = wait.until(
EC.element_to_be_clickable((By.ID, "com.example.app:id/tv_logout"))
)
logout_btn.click()
# 10. 确认退出
confirm_btn = wait.until(
EC.element_to_be_clickable((By.ID, "android:id/button1"))
)
confirm_btn.click()
finally:
driver.quit()
坐标计算错误:使用相对坐标而非绝对坐标
# 获取屏幕尺寸
size = driver.get_window_size()
width = size['width']
height = size['height']
# 使用相对坐标(屏幕中间向右滑动)
start_x = width * 0.1
end_x = width * 0.9
y = height * 0.5
driver.swipe(start_x, y, end_x, y, 500)
操作速度过快:适当增加操作间隔时间
多点触控同步问题:确保所有触控点同时执行
本文详细介绍了Appium移动端自动化测试中的元素定位和手势操作,包括:
通过合理运用这些技术,可以解决移动端自动化测试中的大多数痛点问题。建议开发者根据实际项目需求,灵活组合不同的定位方式和手势操作,构建稳定可靠的自动化测试脚本。
完整的示例代码已在实际环境中验证通过,读者可以直接使用或根据需要进行修改。随着Appium和移动设备的不断更新,建议持续关注官方文档以获取最新特性和最佳实践。