zoukankan      html  css  js  c++  java
  • uiautomator设备和选择器~Python详解

    1、设备对象

    引入uiautomator,获取设备对象<所谓设备对象可理解为:Android模拟器或者真机>

    语法:from uiautomator import device as d

    d 即为设备对象

    1.1、获取设备信息

    语法:d.info

    返回值:

    { u'displayRotation': 0,
      u'displaySizeDpY': 640,
      u'displaySizeDpX': 360,
      u'currentPackageName': u'com.android.launcher',
      u'productName': u'takju',
      u'displayWidth': 720,
      u'sdkInt': 18,
      u'displayHeight': 1184,
      u'naturalOrientation': True
    }

    返回值解释如下:

    displayRotation  0 代表竖屏 1 代表横屏

    currentPackageName  当前的Activity的Package名字

    productName  当前设备名称

    displayWidth  当前设备屏幕宽度  当 displayRotation 取值为 1 时,也就是说当前是横屏状态时,displayWidth 取值会和 displayHeight 互换

    displayHeight 当前设备屏幕高度  当 displayRotation 取值为 1 时,也就是说当前是横屏状态时,displayHeight 取值会和 displayWidth 互换

    sdkInt 当前SDK版本

    naturalOrientation 当 displayRotation 取值为 1 时,也就是说当前是横屏状态时,取值为False,为竖屏状态时,取值为:True

    1.2、点亮或熄灭屏幕(Turn on/off screen)

    # 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()

    检查屏幕状态,关闭OR点亮?

    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)

    下面的这些按键也是被支持的,如下:

    Next keys are currently supported:

    • home                   #手机Home键
    • back                   #手机返回键
    • left                   #对应键盘上的向右键<-
    • right                  #对应键盘上的向右键->
    • up                    #对应键盘上的向上键
    • down                   #对应键盘上的向下键
    • center                  #选中?
    • menu                   #菜单
    • search                  #查找?
    • enter                  #对应键盘上的Enter键
    • delete(or del)                          #对应键盘上的DEL键 用于删除
    • recent(recent apps)                  #任务切换
    • volume_up                #声音向上调整
    • volume_down               #声音向下调整
    • volume_mute               #静音按键
    • camera                  #拍照
    • power                   #电源键

    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、屏幕操作及屏幕方向获取与控制<上述:displayRotation  0 代表竖屏 1 代表横屏>,竖屏分为 natural(自然的,正常的竖屏) 和 upsidedown(倒过来的竖屏),横屏分为向左和向右两个方向,分别为:left 和 right 

    设备属性:orientation 可能取得值为:

    • natural or n
    • left or l
    • right or r
    • upsidedown or u (can not be set)

    说明:在手机设备上,倒过来的屏幕很少见,因此:d.orientation 取值 upsidedown 的可能性几乎没有

    # 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")

    打开通知或快速设置

    # 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()

    注意:(如果notification已经打开了,调用d.open.quick_settings()不会打开快速设置)

    等待空闲或窗口更新(Wait for idle or window update)

    # wait for current window to idle
    d.wait.idle()
    # wait until window update event occurs
    d.wait.update()

    2、uiautomator 选择器

    选择器是在当前窗口中标识特定的UI对象。可理解为:UiObject对象

    目前,在uiautomator中支持以下属性选择器:

    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

    下面依次进行解读:

    2.1、text选择器(支持在uiautomator中Text属性不为空的元素)

    例如:

    具体用法如下:

    d(text="Maps").click()
    #当然也可以多个属性在一块使用
    d(text="Maps",className="android.widget.TextView").click()
    #或者
    d(text="Maps",className="android.widget.TextView",packageName="com.google.android.apps.nexuslauncher").click()

    总之:要尽可能的使用选择器唯一确定一个被选择对象(UiObject)

    除了可以进行选择UiObject对象以外,我们亦可以使用选择器设置某些元素的值,如下:

    #输入短信目标手机号
    d(text="To").set_text("10086")
    #如果本窗口中有多个text为To的元素,我们也可以使用多属性选择
    d(text="To",packageName="com.google.android.apps.messaging").set_text("10086").set_text("10086")

    textContains,textMaches,textStartsWith 分别代表:包含,正则表达式,以XXX开头等

    例如:

    d(text="Name").set_text("John")

    d(textContains="ame").set_text("John")

    d(textStartsWith="Nam").set_text("John")

    2.2、className,classNameMatches 类选择器 及 descriptiondescriptionContainsdescriptionMatchesdescriptionStartsWith 描述选择器 及 packageNamepackageNameMatches 包选择器 及 resourceIdresourceIdMatches ResId选择器用法和text选择器类似,都可以多属性选择器结合在一起使用。

    示例代码如下:

    # To seleted the object ,text is 'Clock' and its className is 'android.widget.TextView'
    d(text='Clock', className='android.widget.TextView')
    d(description="add new contact").click()
    d(descriptionContains="new contact").click()
    d(descriptionStartsWith="add new").click()
    #resourceid选择器
    d(resourceId="com.android.contacts:id/menu_save").click()
    #text选择器
    d(textStartsWith="Nam").set_text("John")
    #描述选择器
    d(descriptionContains="new contact").click()
    #多属性结合
    d(text="Name",className="android.widget.EditText").set_text("John")
    #index选择器和child选择器
    d(resourceId="com.android.settings:id/list").child(className="android.widget.LinearLayout", index=2).child(resourceId="android:id/widget_frame").child(resourceId="android:id/switch_widget").click()

    在此,说明下child、sibling选择器和index选择器及instance选择器(严格讲instance不是选择器,仅仅只是在输出多个结果的情况下,可以通过索引(下标)进行选择)

    首先说明child选择器,sibling选择器:分别可理解为:子选择器(可嵌套),兄弟姐妹选择器

    如上图右边部分,从上到下层次分为四层,最后一层的两个元素可理解为兄弟姐妹,在此,我们如果要选择最下面的那个元素就可以用到child选择器及sibling选择器,当然,本人不建议使用孩子,兄妹选择器,如果能用其他方法实现,建议用其他方法:

    在此,我写的方法如下:<没有具体验证,仅仅只是演示>

    #孩子选择器及兄弟姐妹选择器的用法:child/sibling
    d(resourceId="id/pager").child(className="android.widget.FrameLayout").child(resourceId="id/empty_view").child(resourceId="id/empty_image_hint").sibling(packageName="com.google.android.apps.messaging")

    2.3、index选择器及instance,比较容易混淆的两个,一个是选择器,一个代表索引,如下:

    index选择器对应uiautomator的index属性,如下:

    其用法和text选择器大同小异,不过在此需要指出的是,有些窗体中index取值会发生改变,因此,能不用index选择器的,尽可能不用!

    #index选择器
    d(className="android.widget.LinearLayout", index=2).click()

    instance 的用法:当你的选择器返回的结果不是指向唯一元素时(两个或者多个),你可以通过instance进行选择。

    贺晓聪原文:

    Multiple instances

    Sometimes the screen may contain multiple views with the same e.g. text, then you will have to use "instance" properties in selector like below:

    d(text="Add new", instance=0)  # which means the first instance with text "Add new"

    However, uiautomator provides list like methods to use it.

    # get the count of views with text "Add new" on current screen
    d(text="Add new").count
    
    # same as count property
    len(d(text="Add new"))
    
    # get the instance via index
    d(text="Add new")[0]
    d(text="Add new")[1]
    ...
    
    # iterator
    for view in d(text="Add new"):
        view.info  # ...

    2.4、获取选定的UI对象状态及其信息(Get the selected ui object status and its information)

    检测特定的UI对象是否存在(Check if the specific ui object exists)

    两种写法,如下:

    d(text="Settings").exists # True if exists, else False
    d.exists(text="Settings") # alias of above property.

    检索特定UI对象的信息(Retrieve the info of the specific ui object)

    d(text="Settings").info

    (结果为列表List),如下:

    { u'contentDescription': u'',
      u'checked': False,
      u'scrollable': False,
      u'text': u'Settings',
      u'packageName': u'com.android.launcher',
      u'selected': False,
      u'enabled': True,
      u'bounds': {u'top': 385,
                  u'right': 360,
                  u'bottom': 585,
                  u'left': 200},
      u'className': u'android.widget.TextView',
      u'focused': False,
      u'focusable': True,
      u'clickable': True,
      u'chileCount': 0,
      u'longClickable': True,
      u'visibleBounds': {u'top': 385,
                         u'right': 360,
                         u'bottom': 585,
                         u'left': 200},
      u'checkable': False
    }

    设置/清除字段或编辑文本

    d(text="Settings").clear_text()  # clear the text
    d(text="Settings").set_text("My text...")  # set the text

    执行单击特定的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()

    长时间点击特定的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()

    将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)  拖拽到text='Clock'的对象位置上
    d(text="Settings").drag.to(text="Clock", steps=50)

    滑动UI对象

    滑动分为四个方向:left ,right,top ,bottom 即:左滑动 右滑动 上滑动 及向下滑动

    d(text="Settings").swipe.right()
    d(text="Settings").swipe.left(steps=10)
    d(text="Settings").swipe.up(steps=10)
    d(text="Settings").swipe.down()

    Two point gesture from one point to another

    d(text="Settings").gesture((sx1, sy1), (sx2, sy2)) .to((ex1, ey1), (ex2, ey2))

    Two point gesture on the specific ui object

    Supports two gestures:

    • In, from edge to center
    • Out, from center to edge
    # 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()

    3 point gesture

    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))

    等到特定的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)

    在具体的UI对象执行甩(滚动)Perform scroll on the specific ui object(scrollable)

    Possible properties:

    • horiz or vert
    • forward or backward or toBeginning or toEnd
    # 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()

    Perform scroll on the specific ui object(scrollable)-在具体的UI对象执行甩(滚动)

    Possible properties:

    • horiz or vert
    • forward or backward or toBeginning or toEnd, or to
    # 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")
  • 相关阅读:
    考试 题目
    引用数据类型 Scanner和 Random
    数组
    数据字典 事物 序列 索引视图
    小程序下拉刷新
    使用e.target.dataset的问题
    动态统计当前输入内容的字节、字符数
    小程序根据input输入,动态设置按钮的样式
    小程序刨坑(一)
    charles 踩坑记录
  • 原文地址:https://www.cnblogs.com/wanghzh/p/9372005.html
Copyright © 2011-2022 走看看