zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

Android自动化测试框架uiautomator2详解

2023-09-11 14:20:52 时间

1 uiautomator2 简介

        uiautomator2 是 一种 Android 自动化测试框架,提供了点击、长按、输入文本、滑动、拖拽、截屏等方法,能够模拟用户的各种动作。用户可以通过控件的 id 或 text 等属性,定位到控件,从而对控件实施上述操作。

2 环境搭建

        1)python 环境变量配置

        安装好 python3.7 后,将【D:\Program Files\Python 3.7】和【D:\Program Files\Python 3.7\Scripts】添加到系统环境变量中的path 中,可以通过在 cmd 界面输入 python 命令检验 python 环境变量是否配好。

        2)pycharm 编码设置

        安装好 pycharm 后,需要设置编码格式,避免乱码,主要设置以下3项:

  • 【File】→【Settings】→【Editor】→【File Encodings】→【Global Encoding】、【Project Encoding】、【Default encoding for properties files】都设置为 UTF-8
  • 工作区域右下角设置编码格式为 UTF-8,如右图:
  • 【Appearance & Behavior】→【Appearance】→选中【Override default fonts by (not recommended)】复选框,【Name】设置为 Microsoft Yahei

        3)uiautomator2 安装

        打开 pycharm,运行以下代码。

        install.py

import os

# https://pypi.douban.com/simple  # 豆瓣镜像
# https://pypi.tuna.tsinghua.edu.cn/simple  # 清华镜像

mirror = " -i https://pypi.douban.com/simple"

os.system("python -m pip install --upgrade pip" + mirror)  # 更新 pip
os.system("pip install --pre -U uiautomator2" + mirror)  # 安装 uiautomator2
os.system("pip install --pre weditor" + mirror)  # 安装 weditor
os.system("python -m uiautomator2 init")  #安装 atx-agent 至手机

         注意事项及说明:

        1. 若内网无法下载,请使用手机给 PC 开个热点;

        2. weditor 是一种页面信息查看工具,可以查看页面包名、运行的Activity,页面布局、控件等信息;

        3. 若执行【python -m uiautomator2 init】命令失败(此命令需要用 USB 线连接手机),可能是 5037 端口已被其他进程占用,可以在 cmd 界面使用 【netstate -ano | findstr "5037"】命令查看占用该端口的进程,然后使用【adb shell kill -9 pid】命令 kill 掉占用 5037 端口的进程,其中 pid 为查询出的占用 5037 端口的进程号,若仍然无效,再执行以下命令:

  • adb kill-server
  • adb start-server
  • adb remount

        执行完上述命令后,再执行【python -m uiautomator2 init】,若成功执行,手机上会安装【com.github.uiautomator.test】(此应用无界面,需要在“应用管理”中查看)和【ATX】。

3 界面信息查看工具

        用户可以通过点击按钮所在坐标,实现对按钮的控制,但是,只通过坐标不能获取对文本框的控制权。好在手机界面上的控件,一般都有 resourceId 、text、description、className 等属性,用户通过这些属性,可以轻松定位到指定控件,从而实现对控件的控制。

3.1 weditor

        在第 2 节中通过【pip install --pre weditor -i https://pypi.douban.com/simple】命令,顺便安装了 weditor。

        用户通过在 cmd 界面执行【python -m weditor】命令,打开 weditor,界面如下:

        注意事项: 用户需要在手机上打开【ATX】软件,点击【启动UIAUTOMATOR】,并且保证手机和 PC 连在同一个 wifi 上,当【Connect】旁边的图标变绿,说明连接成功,用户可以通过点击【Dump Hierarchy】同步手机界面。

3.2 uiautomatorviewer

        uiautomatorviewer 是 Android SDK 中提供的页面信息查看工具,位置:【D:\Program\sdk\tools\uiautomatorviewer.bat】,用户通过单击此文件,进入如下界面:

        注意事项:

        1)使用 Android Studio 下载最新的 platform-tools 和 tools

        2)配置系统环境变量:【ANDROID_SWT】(key)——【D:\Program\sdk\tools\lib\x86_64】(value),并将【D:\Program\sdk\tools】和【D:\Program\sdk\platform-tools】添加到系统环境变量的 path 中。

        3)必须关闭【ATX】

4 uiautomator2 常用API

        在应用 uiautomator2 框架时,需要导入包,如下:

import uiautomator2 as u2

4.1 设备连接

        设备连接主要分为有线连接和无线连接,如下:

# 有线连接
d = u2.connect_usb(id)  # id 为 adb devices 命令中得到的设备 id

# 无线连接
d = u2.connect(ip)  # ip 为 手机 ip

        说明:返回的 d 为连接句柄,通过 d 可以实现对手机的操作。 

4.2 应用控制

        1)安装应用

d.app_install('http://domain.com/xxx.apk')

注意:只能从 URL 安装 

        2)打开应用

d.app_start("app_package_name")

        3)关闭应用

d.app_stop("app_package_name")

        4)关闭所有应用

d.app_stop_all()

        通过点击 recent 按钮清除所有应用

d.press("recent")  # 点击 recent 键
sleep(1)
d(resourceId="com.huawei.android.launcher:id/clear_all_recents_image_button").click()

4.3 元素定位

        由于页面元素(控件)一般有 resourceId 、text、description、className 等属性,因此可以通过这些属性定位到具体控件。

  • resourceId:控件 id
  • text:控件上显示的文本
  • description:控件描述
  • className:控件所属的类
element = d(resourceId=value)
element = d(text=value)
element = d(description=value)
element = d(className=value)

        说明:d 为 4.2 节中得到的 连接句柄,value 为控件标识类型对应的属性值。

element 是一个列表,因为可能返回多个同属性值控件,如:控件为 ListView,每个 item 的 resourceId 都一样,采用resourceId 定位,就会把整个列表的 item 都返回,用户可以通过 element[index] 来控制指定的控件。当属性值唯一时,可以省略 element[0] 后面的“[0]”,即:element。

        通过以下命令,可以判断属性值对应的元素是否存在。

element.exists  # 属性值唯一
element[index].exists  # 属性值不唯一

4.4 元素控制

        1)单击控件

element[index].click()  # 定位的控件有多个,通过 index 指定某一个
element.click()  # 定位的控件只有一个,等价于 element[0].click()
d.click(x, y)  # 点击具体坐标

        2)双击控件

element[index].double_click()  # 定位的控件有多个,通过 index 指定某一个
element.double_click()  # 定位的控件只有一个,等价于 element[0].double_click()
d.double_click(x, y)  # 双击具体坐标

        3)长按控件

element[index].long_click()  # 定位的控件有多个,通过 index 指定某一个
element.long_click()  # 定位的控件只有一个,等价于 element[0].long_click()
d.long_click(x, y, duration=0.5)  # 长按具体坐标

        4)文本操作

        输入文本:

element[index].set_text(text)  # 定位的控件有多个,通过 index 指定某一个
element.set_text(text)  # 定位的控件只有一个,等价于 element[0].set_text(text)

        另外,当页面中有且仅有一个编辑框时,可以使用以下代码:

d.set_fastinput_ime(True)  # 打开输入法
d.send_keys(text)  # 输入文本
d.set_fastinput_ime(False)  # 关闭输入法

         清除文本:

element[index].clear_text()  # 定位的控件有多个,通过 index 指定某一个
element.clear_text()  # 定位的控件只有一个,等价于 element[0].clear_text()

        获取文本:

element[index].get_text()  # 定位的控件有多个,通过 index 指定某一个
element.get_text()  # 定位的控件只有一个,等价于 element[0].get_text()

4.5 手势控制

        1)滑动

d.swipe(sx, sy, ex, ey, duration=0.5)

        2)拖拽

d.drag(sx, sy, ex, ey, duration=0.5)

4.6 系统控制

        1)按键

# key = {"back", "home", "recent", "power", "volume_up", "volume_down", "volume_mute", "enter",...}
d.press(key)

        2)旋转

        获取屏幕方向:

orientation = d.orientation  # 获取屏幕方向,取值为{"natural", "left", "right", "upsidedown"}

        锁定屏幕方向:

d.freeze_rotation()  # 锁定屏幕方向
d.freeze_rotation(True)  # 解除锁定屏幕方向

        设置屏幕方向: 

d.set_orientation("left")  # 向左转为横屏
d.set_orientation("right")  # 向右转为横屏
d.set_orientation("natural")  # 转为竖屏

        说明:left 、right、natural 可以分别简写为 l、r、n

        3)截屏

image = d.screenshot() 
image.save("path.jpg")

d.screenshot("path.jpg")  # 截屏并保存

        4)push

d.push(pc_file_path, phone_dir_path)  # 将 PC 上的文件 push 到手机上指定目录,若此目录不存在,会自动创建

        5)pull

d.push(pc_file_path, phone_dir_path)  # 将手机端的文件 pull 到 PC 端指定文件夹

4.7 拓展

        通过【adb shell input】,并结合【os.system(command)】也可以实现模拟输入。

::查看模拟输入命令
adb shell input --help
 
::点击指定坐标位置
adb shell input tap <x> <y>
 
::滑动
adb shell input swipe <x1> <y1> <x2> <y2>
 
::按键事件
adb shell input keyevent <keycode>

        说明:通过 -d 属性可以指定 displayId,应用如下:

::点击指定display的指定坐标位置
adb shell input -d 1 tap 100 200

        常用<keycode>如下:

3    HOME 键
4    返回键
5    打开拨号应用
6    挂断电话
24   增加音量
25   降低音量
26   电源键
27   拍照(需要在相机应用里)
64   打开浏览器
82   菜单键
85   播放/暂停
86   停止播放
87   播放下一首
88   播放上一首
122  移动光标到行首或列表顶部
123  移动光标到行末或列表底部
126  恢复播放
127  暂停播放
164  静音
176  打开系统设置
187  切换应用
207  打开联系人
208  打开日历
209  打开音乐
210  打开计算器
220  降低屏幕亮度
221  提高屏幕亮度
223  系统休眠
224  点亮屏幕
231  打开语音助手
276  如果没有 wakelock 则让系统休眠

        详见→adb常用命令总结 

        应用:

import os 

# 返回桌面
os.system("adb shell input keyevent 3")

         模拟点击案例:

@echo off
setlocal EnableDelayedExpansion
 
set /a loop_times=10
adb remount
for /l %%i in (1,1,!loop_times!) do (
	echo **********%%i**********
	call :loop
)
pause
 
::循环体
:loop
	adb shell input tap 500 500
	:wait 3
	adb shell input swipe 500 1000 500 0
	:wait 3
	call :screenshot
	:wait 2
goto:eof
 
::截屏
:screenshot
	adb shell screencap -p /sdcard/1.png
	adb pull /sdcard/1.png 1.png
	set date_temp=%date:~0,10%
	set time_temp=%time:~0,12%
	set time_temp=%time_temp::=-%
	set time_temp=%time_temp:.=-%
	set t=%date_temp:/=-%_%time_temp: =0%
	echo %t%
	set filename=%t%.png
	ren 1.png %filename%
goto:eof
 
::等待
:wait
	choice /T %1 /C ync /CS /D y /n
	::ping 127.0.0.1 -n 1 >nul
goto:eof