执行背景
当前项目研发进度加快,模块化项目增加了模块功能的独立性,但同时也增加了版本之间的出现兼容问题的风险,怎样才能在当前快速迭代的环境中还能保持整体功能的稳定,正是眼前迫切需求。
uiautomator是什么?
功能介绍
uiautomator是Android官方推出的安卓应用界面自动化测试工具,是理想的针对APK进行自动化功能回归测试的利器。能够根据文本、控件id、坐标进行点击、长按、滑动、查找等操作,实现与人一致的手动操作逻辑,根据测试用例使用python编码后根据指定命令操作,检查预期结果,进行测试。最终通过单元测试执行用例脚本生成相应报告。
python环境下使用教程
1.python3环境
2.安装uiautomator
pip install uiautomator
3.导包
from uiautomator import Device
d = Device('emulator-5554')# 设备名称,可通过adb devices查看获取
3.API介绍
1. 先看看常用的基本API
1.1 获取机器的信息
代码如下,
d.info
下面是可能的结果(因机器不同而异),
{u'displayRotation': 0,
u'displaySizeDpY': 640,
u'displaySizeDpX': 360,
u'screenOn': True,
u'currentPackageName': u'com.android.launcher3',
u'productName': u'DeviceX',
u'displayWidth': 720,
u'sdkInt': 25,
u'displayHeight': 1280,
u'naturalOrientation': True}
1.2 屏幕相关的操作
开关屏幕,代码如下
# Turn on screen
d.screen.on()
# Turn off screen
d.screen.off()
效果等同如下代码,
# wakeup the device
d.wakeup()
# sleep the device, same as turning off the screen.
d.sleep()
查看屏幕是否点亮,代码如下,
if d.screen == "on": # of d.screen != "off"
# do something in case of screen on
pass
if d.screen == "off": # of d.screen != "on"
# do something in case of screen off
pass
1.3 按(软/硬)键操作
# press home key
d.press.home()
# press back key
d.press.back()
# the normal way to press back key
d.press("back")
# press keycode 0x07('0') with META ALT(0x02) on
d.press(0x07, 0x02)
还支持如下按键的操作,
home
back
left
right
up
down
center
menu
search
enter
recent(recent apps)
volume_up
volume_down
volume_mute
camera
power
更多按键定义,请移步至Android官网 AndroidKeyEvent
1.4 手势相关的存在,包括 短按/长按/滑动/拖拽
短按操作,
# click (x, y) on screen
d.click(x, y)
长按操作,
# long click (x, y) on screen
d.long_click(x, y)
滑动操作,
# swipe from (sx, sy) to (ex, ey)
d.swipe(sx, sy, ex, ey)
# swipe from (sx, sy) to (ex, ey) with 10 steps
d.swipe(sx, sy, ex, ey, steps=10)
拖拽操作,
# drag from (sx, sy) to (ex, ey)
d.drag(sx, sy, ex, ey)
# drag from (sx, sy) to (ex, ey) with 10 steps
d.drag(sx, sy, ex, ey, steps=10)
1.5 屏幕相关的操作
获取并设置屏幕的旋转方向,
# retrieve orientation, it may be "natural" or "left" or "right" or "upsidedown"
orientation = d.orientation
# set orientation and freeze rotation.
# notes: "upsidedown" can not be set until Android 4.3.
d.orientation = "l" # or "left"
d.orientation = "r" # or "right"
d.orientation = "n" # or "natural"
冻结/解冻旋转功能,
# freeze rotation
d.freeze_rotation()
# un-freeze rotation
d.freeze_rotation(False)
屏幕截图,
# take screenshot and save to local file "home.png", can not work until Android 4.2.
d.screenshot("home.png")
获取屏幕层级(hierachy)XML
# dump the widown hierarchy and save to local file "hierarchy.xml"
d.dump("hierarchy.xml")
# or get the dumped content(unicode) from return.
xml = d.dump()
打开通知栏或快速设置栏,
# open notification, can not work until Android 4.3.
d.open.notification()
# open quick settings, can not work until Android 4.3.
d.open.quick_settings()
等待窗口休眠或更新,
# wait for current window to idle
d.wait.idle()
# wait until window update event occurs
d.wait.update()
2. Watcher
功能:开启守护进程,当符合条件时,完成特点的动作,如点击按钮等。
2.1 注册Watcher
示例一,
d.watcher("AUTO_FC_WHEN_ANR").when(text="ANR").when(text="Wait").click(text="Force Close")
示例二,
d.watcher("AUTO_FC_WHEN_ANR").when(text="ANR").when(text="Wait").press.back.home()
# Alternative way to define it as below
d.watcher("AUTO_FC_WHEN_ANR").when(text="ANR").when(text="Wait").press("back", "home")
# d.watcher(name) ## creates a new named watcher.
# .when(condition) ## the UiSelector condition of the watcher.
# .press.<keyname>.....<keyname>.() ## press keys one by one in sequence.
# Alternavie way defining key sequence is press(<keybname>, ..., <keyname>)
2.2 查看某个Watcher是否被触发
d.watcher("watcher_name").triggered
# true in case of the specified watcher triggered, else false
2.3 移除某个Watcher
# remove the watcher
d.watcher("watcher_name").remove()
2.4 列出所有已经注册的Watcher
d.watchers
# a list of all registered wachers' names
2.5 查看是否有任何一个Watcher曾经被触发
d.watchers.triggered
# true in case of any watcher triggered
2.6 复位所有已经被触发的Watcher
# reset all triggered watchers, after that, d.watchers.triggered will be false.
d.watchers.reset()
2.7 移除Watcher
# remove all registered watchers
d.watchers.remove()
# remove the named watcher, same as d.watcher("watcher_name").remove()
d.watchers.remove("watcher_name")
2.8 强制运行所有已经注册的Watcher
# force to run all registered watchers
d.watchers.run()
3. Handler
和Watcher类似,但可以呼叫回调函数,示例代码如下,
def fc_close(device):
if device(text='Force Close').exists:
device(text='Force Close').click()
return True # return True means to break the loop of handler callback functions.
# turn on the handler callback function
d.handlers.on(fc_close)
# turn off the handler callback function
d.handlers.off(fc_close)
4. 选择器(Selector)
选择器(Selector)是用来识别当前屏幕的对象,它可以通过对象的下列属性来识别,
- text, textContains, textMatches, textStartsWith
- className, classNameMatches
- description, descriptionContains, descriptionMatches, descriptionStartsWith
- checkable, checked, clickable, longClickable
- scrollable, enabled,focusable, focused, selected
- packageName, packageNameMatches
- resourceId, resourceIdMatches
- index, instance
示例代码如下,
# To seleted the object ,text is 'Clock' and its className is 'android.widget.TextView'
d(text='Clock', className='android.widget.TextView')
4.1 通过父子关系选择
# get the child or grandchild
d(className="android.widget.ListView").child(text="Bluetooth")
4.2 通过宗族关系选择
# get sibling or child of sibling
d(text="Google").sibling(className="android.widget.ImageView")
4.3 通过相对位置选择,支持left/right/up/down,
示例代码如下,
## select "switch" on the right side of "Wi‑Fi"
d(text="Wi‑Fi").right(className="android.widget.Switch").click()
4.4 检查当前屏幕UI对象是否存在
d(text="Settings").exists # True if exists, else False
d.exists(text="Settings") # alias of above property.
4.5 得到UI对象的信息
d(text="Settings").info
4.6 设置/清理可编辑文本的内容,
d(text="Settings").clear_text() # clear the text
d(text="Settings").set_text("My text...") # set the text
4.7 对UI对象点击
# click on the center of the specific ui object
d(text="Settings").click()
# click on the bottomright corner of the specific ui object
d(text="Settings").click.bottomright()
# click on the topleft corner of the specific ui object
d(text="Settings").click.topleft()
# click and wait until the new window update
d(text="Settings").click.wait()
4.8 对UI对象长按点击
# long click on the center of the specific ui object
d(text="Settings").long_click()
# long click on the bottomright corner of the specific ui object
d(text="Settings").long_click.bottomright()
# long click on the topleft corner of the specific ui object
d(text="Settings").long_click.topleft()
4.9 拖到UI对象到另外一个坐标或者另外一个UI对象
# notes : drag can not be set until Android 4.3.
# drag the ui object to point (x, y)
d(text="Settings").drag.to(x, y, steps=100)
# drag the ui object to another ui object(center)
d(text="Settings").drag.to(text="Clock", steps=50)
4.10 滑动(swipe),支持四个方向,left/right/up/down,
d(text="Settings").swipe.right()
d(text="Settings").swipe.left(steps=10)
d(text="Settings").swipe.up(steps=10)
d(text="Settings").swipe.down()
4.11 双指操作,
d(text="Settings").gesture((sx1, sy1), (sx2, sy2)).to((ex1, ey1), (ex2, ey2))
4.12 双指操作,两手指往里捏(In),两手指往外捏(Out)
# notes : pinch can not be set until Android 4.3.
# from edge to center. here is "In" not "in"
d(text="Settings").pinch.In(percent=100, steps=10)
# from center to edge
d(text="Settings").pinch.Out()
4.13 三指手势
d().gestureM((sx1, sy1), (sx2, sy2),(sx3, sy3)).to((ex1, ey1), (ex2, ey2),(ex3,ey3))
d().gestureM((100,200),(300,200),(600,200),(100,600),(300,600),(600,900))
4.14 等待UI对象的出现或者消失
# wait until the ui object appears
d(text="Settings").wait.exists(timeout=3000)
# wait until the ui object gone
d(text="Settings").wait.gone(timeout=1000)
4.15 滑动操作,支持水平和垂直滑动,
# fling forward(default) vertically(default)
d(scrollable=True).fling()
# fling forward horizentally
d(scrollable=True).fling.horiz.forward()
# fling backward vertically
d(scrollable=True).fling.vert.backward()
# fling to beginning horizentally
d(scrollable=True).fling.horiz.toBeginning(max_swipes=1000)
# fling to end vertically
d(scrollable=True).fling.toEnd()
4.16 滚到操作,支持水平和垂直滚动
# scroll forward(default) vertically(default)
d(scrollable=True).scroll(steps=10)
# scroll forward horizentally
d(scrollable=True).scroll.horiz.forward(steps=100)
# scroll backward vertically
d(scrollable=True).scroll.vert.backward()
# scroll to beginning horizentally
d(scrollable=True).scroll.horiz.toBeginning(steps=100, max_swipes=1000)
# scroll to end vertically
d(scrollable=True).scroll.toEnd()
# scroll forward vertically until specific ui object appears
d(scrollable=True).scroll.to(text="Security")
版权归原作者 蓝色的天空yyy 所有, 如有侵权,请联系我们删除。