本次我们将会学习 uiautomator2 的一些基本操作,并通过这些基本操作,完成对手机里的应用进行简单的自动化操作。
import uiautomator2 as u2 # USB方式,需确保能够通过 adb 命令获取到手机设备序列号(如 c01bcd5d ) d = u2.connect('c01bcd5d') # Wifi方式,需确保当前设备的IP(如192.168.1.12),和电脑处于同一网络下 d = u2.connect('192.168.1.12') # 可以不带参数,此时会从环境变量中取设备IP或序列号,如果环境变量为空,则使用 connect_usb() d = u2.connect()
d.info
d.device_info
d.window_size()
d.serial
d.wlan_ip
# 启动app d.app_start("com.sec.android.app.popupcalculator") # 通过指定 app activity 的方式启动app d.app_start("com.netease.cloudmusic", ".activity.LoadingActivity") # 先执行关闭app操作,再重新启动app d.app_start("com.netease.cloudmusic", ".activity.LoadingActivity", stop=True)
# 停止单个应用 d.app_stop("com.netease.cloudmusic") # 停止所有应用 d.app_stop_all() # 停止除了某个应用外的其他应用 d.app_stop_all(excludes=['com.netease.cloudmusic'])
d.app_clear("com.netease.cloudmusic")
d.app_current()
d.app_list_running()
d.app_info("com.sec.android.app.popupcalculator")
d.screen_on()
d.screen_off()
d.info.get('screenOn')
# 根据坐标点击 d.click(x, y) # 根据定位的元素对象点击 d(resourceId="com.sec.android.app.popupcalculator:id/bt_equal").click() d(text="=").click() d(description="等于").click() d(className="android.widget.EditText").click() d.xpath('//*[@resource-id="com.sec.android.app.popupcalculator:id/bt_equal"]').click()
d.double_click(x, y)
d.long_click(x, y)
# fx/fy为起始坐标,tx/ty为目标坐标 d.swipe(fx, fy, tx, ty) # fx/fy为起始坐标,tx/ty为目标坐标,在1.0s内进行滑动 d.swipe(fx, fy, tx, ty, duration=1.0) # 屏幕上滑/下滑/左滑/右滑 d.swipe_ext("up") d.swipe_ext("down") d.swipe_ext("left") d.swipe_ext("right") # scale为滑动百分比,默认0.9,,滑动距离为屏幕宽度的90% d.swipe_ext("up", scale=0.9)
# 直接保存截图 d.screenshot("C:\\Users\\wintest\Desktop\\home.jpg") # 先获取 PIL.Image 格式图像,再进行保存 image = d.screenshot() image.save("C:\\Users\\wintest\Desktop\\home.jpg")
d.dump_hierarchy()
d.open_notification()
d.open_quick_settings()
# UI对象存在返回 True ,否则返回 False d(resourceId="com.sec.android.app.popupcalculator:id/bt_equal").exists d(text="=").exists d(description="等于").exists d(className="android.widget.EditText").exists d.xpath('//*[@resource-id="com.sec.android.app.popupcalculator:id/bt_equal"]').exists # 也可以是下面这样,存在返回 True ,否则返回 False d.exists(resourceId="com.sec.android.app.popupcalculator:id/bt_equal") d.exists(text="=") d.exists(description="等于") d.exists(className="android.widget.EditText")
d(resourceId="com.sec.android.app.popupcalculator:id/bt_equal").info d(text="=").info d(description="等于").info d(className="android.widget.EditText").info d.xpath('//*[@resource-id="com.sec.android.app.popupcalculator:id/bt_equal"]').info
# 方式一 d.implicitly_wait(10.0) # 方式二 d.settings["wait_timeout"] = 10.0
# 设置输入框文本 d(text="XXX").set_text("xxxx") # 获取输入框文本 d(text="XXX").get_text() # 清空输入框文本 d(text="XXX").clear_text()
d.set_fastinput_ime(True)
d.send_keys("XXX")
d.send_action("search")
d.set_fastinput_ime(False)
d.current_ime()
更多更详细的操作及介绍,大家可以前往 Github 进行学习:https://github.com/openatx/uiautomator2
这里针对手机计算器进行简单的自动化模拟测试。
import uiautomator2 as u2 import time d = u2.connect("192.168.1.12") # 启动计算器 d.app_start("com.sec.android.app.popupcalculator") # 模拟 1+2=3 d(resourceId="com.sec.android.app.popupcalculator:id/bt_01").click() d(resourceId="com.sec.android.app.popupcalculator:id/bt_add").click() d(resourceId="com.sec.android.app.popupcalculator:id/bt_02").click() d(resourceId="com.sec.android.app.popupcalculator:id/bt_equal").click() time.sleep(2) # 点击清除按钮 d(resourceId="com.sec.android.app.popupcalculator:id/bt_clear").click() # 模拟 20*35=700 d(resourceId="com.sec.android.app.popupcalculator:id/bt_02").click() d(resourceId="com.sec.android.app.popupcalculator:id/bt_00").click() d(resourceId="com.sec.android.app.popupcalculator:id/bt_mul").click() d(resourceId="com.sec.android.app.popupcalculator:id/bt_03").click() d(resourceId="com.sec.android.app.popupcalculator:id/bt_05").click() d(resourceId="com.sec.android.app.popupcalculator:id/bt_equal").click() time.sleep(2) # 点击清除按钮 d(resourceId="com.sec.android.app.popupcalculator:id/bt_clear").click() # 模拟 1200-100=1100 d(resourceId="com.sec.android.app.popupcalculator:id/bt_01").click() d(resourceId="com.sec.android.app.popupcalculator:id/bt_02").click() d.double_click(0.38, 0.95) # 数字0的坐标 d(resourceId="com.sec.android.app.popupcalculator:id/bt_sub").click() d(resourceId="com.sec.android.app.popupcalculator:id/bt_01").click() d.double_click(0.38, 0.95) # 数字0的坐标 d(resourceId="com.sec.android.app.popupcalculator:id/bt_equal").click() time.sleep(2) # 点击清除按钮 d(resourceId="com.sec.android.app.popupcalculator:id/bt_clear").click() # 模拟 96/24=4 d(resourceId="com.sec.android.app.popupcalculator:id/bt_09").click() d(resourceId="com.sec.android.app.popupcalculator:id/bt_06").click() d(resourceId="com.sec.android.app.popupcalculator:id/bt_div").click() d(resourceId="com.sec.android.app.popupcalculator:id/bt_02").click() d(resourceId="com.sec.android.app.popupcalculator:id/bt_04").click() d(resourceId="com.sec.android.app.popupcalculator:id/bt_equal").click() time.sleep(2) # 点击历史记录 d(resourceId="com.sec.android.app.popupcalculator:id/history_button").click() # 滑动历史记录 d.swipe(0.35, 0.6, 0.35, 0.9, duration=2.0) # 清除历史记录 d(resourceId="com.sec.android.app.popupcalculator:id/clear_btn").click() time.sleep(2) # 关闭计算器 d.app_stop("com.sec.android.app.popupcalculator")