news 2026/11/2 9:30:28

Python封装Uiautomator2实现Android自动化测试

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python封装Uiautomator2实现Android自动化测试

1. Uiautomator2 项目概述

Uiautomator2 是一个基于 Python 封装的 Android UI 自动化测试框架,它通过 HTTP 协议与运行在 Android 设备上的服务进行通信,实现了对 Android 设备的自动化操作。这个框架的核心价值在于将原生的 UiAutomator API 封装成更易用的 Python 接口,大大降低了 Android 自动化测试的门槛。

1.1 核心功能解析

Uiautomator2 主要提供以下核心功能:

  • 设备控制:包括屏幕操作(点击、滑动、长按等)、按键模拟(Home、Back 等)、屏幕旋转控制等
  • 元素定位:支持多种定位策略(text、className、resourceId 等)和 XPath 表达式
  • 应用管理:应用安装、启动、停止、清除数据等操作
  • 信息获取:获取设备信息、当前应用信息、UI 层级结构等
  • 高级交互:支持手势操作(双指缩放、滑动等)、拖拽、输入文本等

1.2 技术架构解析

Uiautomator2 采用客户端-服务端架构:

设备端:运行一个基于 UiAutomator 的 HTTP 服务(android-uiautomator-server),提供各种 Android 自动化接口。这个服务被打包成一个 jar 文件,通过 adb 安装到设备上运行。

客户端:Python 代码通过 HTTP 协议与设备端通信,调用 UiAutomator 的各种功能。Python 客户端封装了底层 HTTP 请求,提供了更友好的 API。

这种设计带来了几个优势:

  1. 测试代码可以用 Python 编写,比 Java 更简洁
  2. 无需编译打包测试代码为 APK,开发效率更高
  3. 支持热更新测试脚本,无需重新安装应用

2. 环境准备与安装

2.1 环境要求

  • Android 设备:版本 4.4 及以上,已开启开发者选项和 USB 调试
  • Python:3.8 及以上版本
  • ADB:Android Debug Bridge 工具已安装并配置好环境变量

2.2 安装步骤

  1. 安装 uiautomator2 Python 包:
pip install uiautomator2
  1. 验证安装是否成功:
uiautomator2 version # 或 python -m uiautomator2 version
  1. (可选但推荐)安装元素查看工具 uiautodev:
pip install uiautodev uiautodev

2.3 设备初始化

首次连接设备时,需要初始化设备环境:

import uiautomator2 as u2 # 自动安装设备端服务 u2.connect().app_start("com.android.settings")

初始化过程会自动完成以下操作:

  1. 推送 atx-agent 到设备
  2. 安装设备端服务 apk
  3. 启动服务进程

3. 核心功能详解

3.1 设备连接方式

Uiautomator2 支持多种设备连接方式:

  1. 通过 USB 连接(需要 adb 已授权):
d = u2.connect() # 连接默认设备 d = u2.connect("设备序列号") # 连接指定设备
  1. 通过 WiFi 连接(需先通过 USB 连接并开启 WiFi 调试):
d = u2.connect("设备IP:端口")
  1. 通过 transport_id 连接:
import adbutils dev = adbutils.device(transport_id=6) d = u2.connect(dev)

3.2 元素定位策略

Uiautomator2 提供了丰富的元素定位方式:

  1. 基本定位器:
d(text="设置") # 通过文本定位 d(className="android.widget.TextView") # 通过类名定位 d(resourceId="com.android.settings:id/title") # 通过资源ID定位
  1. 组合定位器:
d(text="设置", className="android.widget.TextView")
  1. XPath 定位:
d.xpath('//*[@text="我的"]').click()
  1. 相对定位:
d(text="Wi-Fi").right(className="android.widget.Switch").click()

3.3 常用操作示例

  1. 点击操作:
d(text="设置").click() # 普通点击 d(text="设置").long_click() # 长按
  1. 滑动操作:
d.swipe(0.5, 0.8, 0.5, 0.2) # 从下往上滑动 d.swipe_ext("right") # 向右滑动
  1. 输入文本:
d(className="android.widget.EditText").set_text("Hello")
  1. 获取元素信息:
info = d(text="设置").info print(info["text"], info["bounds"])

4. 高级功能与最佳实践

4.1 等待机制

Uiautomator2 提供了多种等待策略:

  1. 隐式等待(全局生效):
d.implicitly_wait(10.0) # 设置默认等待超时为10秒
  1. 显式等待:
d(text="加载中").wait(timeout=15.0) # 等待元素出现 d(text="完成").wait_gone(timeout=10.0) # 等待元素消失
  1. 条件等待:
d.wait_activity(".MainActivity", timeout=10) # 等待特定Activity

4.2 异常处理

建议在脚本中添加适当的异常处理:

try: d(text="下一步").click(timeout=5) except u2.UiObjectNotFoundError: print("未找到'下一步'按钮") except u2.UiAutomationNotConnectedError: print("设备连接异常")

4.3 性能优化技巧

  1. 减少截图操作:screenshot() 和 dump_hierarchy() 操作较耗时,应尽量减少使用
  2. 合理设置等待时间:避免不必要的长等待
  3. 使用 XPath 缓存:对于复杂 XPath 可以缓存结果
  4. 批量操作:将多个操作合并为一个 shell 命令执行

4.4 常见问题排查

  1. 元素找不到:
  • 检查是否正确连接到设备
  • 确认元素定位表达式是否正确
  • 检查是否有弹窗遮挡
  • 尝试增加等待时间
  1. 操作无响应:
  • 检查设备是否卡顿
  • 尝试增加操作间隔时间
  • 确认是否在正确的页面上下文
  1. 服务异常:
  • 重启设备端服务:d.uiautomator.stop() 然后重新连接
  • 检查设备端日志:adb logcat | grep uiautomator

5. 实际应用案例

5.1 自动化测试脚本示例

以下是一个完整的测试脚本示例,测试一个音乐应用的基本功能:

import uiautomator2 as u2 import pytest @pytest.fixture def device(): d = u2.connect() yield d d.app_stop("com.example.music") def test_play_music(device): # 启动应用 device.app_start("com.example.music", stop=True) # 登录 if device(text="登录").exists: device(text="用户名").set_text("testuser") device(text="密码").set_text("password") device(text="登录").click() # 播放音乐 device.xpath('//*[@text="推荐歌单"]/../*[1]').click() device(text="播放全部").click() # 验证播放状态 assert device(text="暂停").exists # 暂停音乐 device(text="暂停").click() assert device(text="播放").exists

5.2 持续集成集成

Uiautomator2 可以方便地集成到 CI/CD 流程中:

  1. 准备阶段:
  • 连接测试设备或启动模拟器
  • 安装被测应用和测试依赖
  1. 执行阶段:
  • 运行测试脚本
  • 收集测试结果和日志
  • 生成测试报告
  1. 清理阶段:
  • 卸载被测应用
  • 清理测试数据
  • 关闭模拟器(如使用)

示例 Jenkins 配置:

pipeline { agent any stages { stage('Prepare') { steps { sh 'pip install uiautomator2 pytest' sh 'adb install app-debug.apk' } } stage('Test') { steps { sh 'pytest tests/ --html=report.html' } } stage('Report') { steps { archiveArtifacts artifacts: 'report.html' } } } }

6. 扩展与生态

6.1 相关工具

  1. Weditor:基于 Web 的 UI 查看器,支持元素定位和脚本生成
  2. ATX:Android 设备管理工具,支持多设备并行测试
  3. uiautodev:命令行元素查看工具

6.2 插件系统

Uiautomator2 支持通过插件扩展功能,例如:

  1. WebView 插件:支持测试混合应用中的 WebView 内容
  2. OCR 插件:通过图像识别定位元素
  3. 性能监控插件:收集测试过程中的性能数据

6.3 与其他工具的对比

特性Uiautomator2AppiumEspresso
语言支持Python多语言Java/Kotlin
执行速度快中等快
跨平台否是否
学习曲线简单中等较陡
社区支持活跃非常活跃官方支持

选择建议:

  • 需要快速实现 Android 自动化:Uiautomator2
  • 需要跨平台支持:Appium
  • 需要与开发流程深度集成:Espresso

7. 最佳实践与经验分享

7.1 元素定位策略优化

  1. 优先使用 resourceId:最稳定可靠的定位方式
  2. 避免使用绝对 XPath:容易因 UI 变化而失效
  3. 合理使用文本定位:对于多语言应用要谨慎
  4. 组合定位器:提高定位准确性

7.2 测试稳定性提升

  1. 增加重试机制:对于关键操作添加重试逻辑
  2. 添加检查点:在关键步骤后验证预期状态
  3. 处理异常弹窗:使用 watch_context 监控意外弹窗
  4. 设备状态隔离:每个测试用例开始前重置应用状态

7.3 性能调优

  1. 减少不必要的操作:如频繁截图、dump hierarchy
  2. 优化等待策略:避免固定 sleep,使用智能等待
  3. 并行执行:在多设备上并行运行测试用例
  4. 代码优化:复用设备连接,减少重复初始化

7.4 实际项目经验

在大型项目中应用 Uiautomator2 的一些经验:

  1. 分层设计:
  • 基础层:封装常用操作(如登录、导航)
  • 业务层:实现具体测试逻辑
  • 用例层:组织测试场景
  1. 数据驱动:
  • 测试数据与代码分离
  • 支持多种数据源(JSON、Excel、数据库)
  1. 报告增强:
  • 添加操作截图
  • 记录详细日志
  • 生成可视化报告
  1. 设备管理:
  • 自动检测可用设备
  • 设备状态监控
  • 异常自动恢复

8. 常见问题解决方案

8.1 连接问题

问题:无法连接设备

解决方案:

  1. 检查 USB 调试是否开启
  2. 确认 adb devices 能识别设备
  3. 尝试重启 adb 服务:adb kill-server && adb start-server
  4. 检查设备端服务是否运行:adb shell ps | grep atx

8.2 元素定位问题

问题:元素能找到但无法操作

可能原因:

  1. 元素被遮挡
  2. 元素不在当前视图
  3. 需要特殊操作(如长按)

解决方案:

  1. 先滚动到元素可见:d(scrollable=True).scroll.to(text="目标元素")
  2. 尝试其他操作方式:如使用坐标点击
  3. 检查是否有动画在进行,增加适当等待

8.3 兼容性问题

问题:在不同设备或系统版本上行为不一致

解决方案:

  1. 添加设备类型判断:
if d.device_info["brand"] == "xiaomi": # 小米设备特殊处理
  1. 针对不同 Android 版本使用不同策略:
if d.info["sdkInt"] >= 28: # Android 9+ 的特殊处理
  1. 建立设备兼容性矩阵,记录已知问题

8.4 稳定性问题

问题:测试用例时好时坏

解决方案:

  1. 增加重试机制
  2. 添加更严格的等待条件
  3. 优化元素定位策略
  4. 记录失败时的设备状态(截图、日志等)便于分析

9. 进阶话题

9.1 自定义插件开发

Uiautomator2 支持通过插件扩展功能。开发一个简单插件的步骤:

  1. 创建插件类:
from uiautomator2 import Plugin class MyPlugin(Plugin): def __init__(self, d): super().__init__(d) def custom_method(self, arg): return self._rpc_call("customMethod", arg)
  1. 注册插件:
d = u2.connect() d.register_plugin("myplugin", MyPlugin) # 使用插件 d.myplugin.custom_method("test")
  1. 设备端实现对应方法(需要修改 android-uiautomator-server)

9.2 与其他测试框架集成

  1. 与 pytest 集成:
  • 使用 fixture 管理设备连接
  • 添加自定义标记和参数化
  • 集成 allure 生成美观报告
  1. 与 AirTest 结合:
  • 使用 AirTest 进行图像识别
  • 使用 Uiautomator2 进行精确控制
  • 结合两者优势构建混合测试方案
  1. 与 Jenkins 集成:
  • 添加自动化测试阶段
  • 收集测试结果和报告
  • 设置质量门禁

9.3 大规模测试实践

对于需要大规模测试的场景(如兼容性测试):

  1. 设备集群管理:
  • 使用 STF 或类似的设备管理平台
  • 自动化设备分配和释放
  • 设备状态监控
  1. 测试任务调度:
  • 根据设备特性分配测试任务
  • 优先级队列管理
  • 失败任务自动重试
  1. 结果分析与聚合:
  • 收集各设备测试结果
  • 生成综合报告
  • 问题自动分类和跟踪

10. 未来发展与社区

Uiautomator2 作为一个开源项目,持续在以下方面发展:

  1. 新特性开发:
  • 更好的 WebView 支持
  • 增强的图像识别能力
  • 性能监控集成
  1. 生态建设:
  • 开发更多实用插件
  • 完善文档和教程
  • 建立案例库
  1. 社区参与:
  • 鼓励贡献代码
  • 组织技术分享
  • 解决用户问题

对于想要深入参与的用户,可以通过以下方式加入社区:

  • 提交 Issue 报告问题
  • 提交 Pull Request 贡献代码
  • 参与文档翻译和完善
  • 分享使用经验和案例
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/2 9:27:56

Paperclip:React+Node.js+OpenClaw轻量AI Agent协作框架

1. 项目概述:Paperclip 不是回形针,而是一个面向 AI Agent 开发的轻量级 React Node.js 协作框架你搜“paperclip”时,第一反应可能是办公桌抽屉里那枚银色小金属件——但最近半年,在 GitHub 和国内前端技术社区里,“…

作者头像 李华
网站建设 2026/11/2 9:27:56

机器人平台化演进:从ROS到云边端协同的十年变革

1. 机器人平台化十年演进全景观察十年前,当第一批模块化机器人开发套件出现在创客空间时,大多数从业者还难以想象今天机器人技术渗透的广度。如今从工业装配线上的协作机械臂到家庭场景的扫地机器人,平台化设计理念已经彻底改变了机器人开发范…

作者头像 李华
网站建设 2026/11/2 9:27:29

回形针的隐藏学问:从弹性原理到选购与收纳

回形针大概是办公桌上最容易被忽略的小东西。它通常躺在一个塑料盒里,或者零散地贴在冰箱门上,偶尔被抽出来夹几张纸、当个书签,然后又被忘掉。我自己是在一次整理财务凭证时才开始认真研究它的——上千份合同要用回形针临时分类,…

作者头像 李华
网站建设 2026/11/2 9:27:27

蓝桥杯真题解析:数位和排序算法实现与优化

1. 题目解析与需求理解这道蓝桥杯省赛真题的核心要求是:对1到n的所有整数按照特定规则排序后,找出第m个元素。排序规则有两个优先级:首先比较数字的数位之和(即各位数字相加的总和)当数位之和相同时,则比较…

作者头像 李华
网站建设 2026/11/2 9:26:56

学术论文写作工具推荐与使用指南

1. 论文写作工具的价值与现状写论文这件事,从本科生到博士生都头疼。特别是对于专科生来说,第一次接触学术写作,往往连基本格式都搞不清楚。我带了五届专科毕业班,每年答辩季都能看到学生们熬夜改格式、查重、调目录的狼狈样。去年…

作者头像 李华
网站建设 2026/11/2 9:26:54

Gobot事件驱动机器人开发:事件模型、并发背压与真机排错

1. 轮询之外的第二条路:机器人程序为什么该由事件驱动我第一次写机器人控制程序的时候,main 函数里就是一个for死循环,每一轮读一遍传感器,判断一下阈值,然后决定电机转不转。这个写法在单传感器、低速度的场景下跑得挺…

作者头像 李华