移动端自动化测试Appium,从入门到项目实战Python版

Appium移动端自动化测试(Python版):元素定位与手势操作全解析

本文将全面介绍如何使用Python+Appium进行移动端自动化测试,重点解决元素定位和手势操作中的常见痛点问题,并提供详细的源码示例。

一、环境搭建与基础配置

1.1 环境准备

要开始Appium自动化测试,首先需要搭建好运行环境:

  1. 安装Appium Server :可以通过Appium官网下载桌面版,或通过npm安装命令行版(npm install -g appium)
  2. Android SDK:提供adb等必要工具,确保配置好环境变量
  3. Python环境 :安装Appium-Python-Client库(pip install Appium-Python-Client)

1.2 初始化设置

连接真机或模拟器后,需要进行初始化配置:

python 复制代码
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)  # 等待应用启动

二、元素定位方法与实战

2.1 常用元素定位方法

Appium提供了多种元素定位方式,以下是6种最常用的方法:

  1. ID定位:通过resource-id属性定位

    python 复制代码
    driver.find_element_by_id("com.example.app:id/btn_login").click()
  2. Class Name定位:通过控件类名定位

    python 复制代码
    driver.find_element_by_class_name("android.widget.Button").click()
  3. XPath定位:通过XPath表达式定位

    python 复制代码
    driver.find_element_by_xpath('//android.widget.Button[@text="登录"]').click()
  4. Accessibility ID(content-desc)定位:通过content-desc属性定位

    python 复制代码
    driver.find_element_by_accessibility_id("搜索按钮").click()
  5. UIAutomator定位:使用Android UIAutomator API定位

    python 复制代码
    driver.find_element_by_android_uiautomator('new UiSelector().text("确定")').click()
  6. 组合定位:结合多种属性定位

    python 复制代码
    driver.find_element_by_xpath('//android.widget.Button[contains(@text,"登")]').click()

2.2 元素定位痛点解决方案

痛点1:动态ID问题

有些元素的ID是动态生成的,每次运行都会变化。解决方案:

  • 使用其他相对稳定的属性组合定位
  • 使用XPath的部分匹配功能
python 复制代码
# 使用contains函数匹配部分文本
driver.find_element_by_xpath('//*[contains(@resource-id,"btn_")]').click()

痛点2:列表元素定位

对于列表中的相似元素,可以通过索引或特定属性定位:

python 复制代码
# 通过索引定位列表中的第三个元素
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:等待元素出现

使用显式等待解决元素加载延迟问题:

python 复制代码
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()

三、手势操作详解

3.1 基本手势操作

  1. 点击与长按
python 复制代码
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()
  1. 滑动与拖动
python 复制代码
# 从(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()
  1. 多点触控
python 复制代码
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()

3.2 高级手势操作

  1. 九宫格解锁
python 复制代码
# 定义九宫格坐标点
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()
  1. 双指缩放
python 复制代码
# 双指放大
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()

四、实战案例:完整自动化测试脚本

下面是一个完整的自动化测试示例,模拟用户登录、浏览和退出应用的过程:

python 复制代码
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()

五、常见问题与解决方案

5.1 元素定位失败问题

  1. 页面未加载完成:增加等待时间,使用显式等待
  2. 元素在屏幕外:先滑动到元素可见区域
  3. 动态元素:使用相对定位或正则表达式匹配

5.2 手势操作不生效问题

  1. 坐标计算错误:使用相对坐标而非绝对坐标

    python 复制代码
    # 获取屏幕尺寸
    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)
  2. 操作速度过快:适当增加操作间隔时间

  3. 多点触控同步问题:确保所有触控点同时执行

六、总结

本文详细介绍了Appium移动端自动化测试中的元素定位和手势操作,包括:

  1. 6种常用元素定位方法及其适用场景
  2. 多种手势操作的实现方式,从基础点击到复杂多点触控
  3. 完整实战案例演示自动化测试流程
  4. 常见问题分析与解决方案

通过合理运用这些技术,可以解决移动端自动化测试中的大多数痛点问题。建议开发者根据实际项目需求,灵活组合不同的定位方式和手势操作,构建稳定可靠的自动化测试脚本。

完整的示例代码已在实际环境中验证通过,读者可以直接使用或根据需要进行修改。随着Appium和移动设备的不断更新,建议持续关注官方文档以获取最新特性和最佳实践。

相关推荐
天才测试猿3 小时前
WebUI自动化测试:POM设计模式全解析
自动化测试·软件测试·python·selenium·测试工具·设计模式·测试用例
MonkeyKing_sunyuhua3 小时前
python线程间怎么通信
android·网络·python
跳跳的向阳花4 小时前
01、大模型部署方案与Dify的使用
python
西柚小萌新4 小时前
【Python从入门到精通】--Pycharm增加内存
开发语言·python·pycharm
西柚小萌新4 小时前
【深入浅出PyTorch】--7.1.PyTorch可视化1
人工智能·pytorch·python
我是华为OD~HR~栗栗呀4 小时前
华为OD-23届考研-Java面经
java·c++·后端·python·华为od·华为·面试
Small___ming4 小时前
【Python基础】Python路径操作全解析:os.path、glob与pathlib从入门到精通
开发语言·python
这里有鱼汤4 小时前
3步用Python识别MACD背驰,避免80%追涨杀跌陷阱,建议收藏
后端·python
程序员爱钓鱼5 小时前
Python编程实战 · 基础入门篇 | Python能做什么
后端·python·github