zoukankan      html  css  js  c++  java
  • appium 元素定位方法

    一、常用识别元素的工具

    uiautomator:Android SDK自带的一个工具,在tools目录下

    monitor:Android SDK自带的一个工具,在tools目录下

    Appium Inspector:Appium自带的一个功能,只有mac下可以使用该功能

    • 下面是用monitor抓取到的页面元素

    • 下面使用Appium Inspector定位的元素

    二、元素定位

    1.格式:find_element_by_定位方式(value)

    • 通过id定位

    (取resource-id的值):

    driver.find_element_by_id("com.wuba.zhuanzhuan:id/azo")

    也可以直接用id后面的内容driver.find_element_by_id("azo")

    • 通过class_name定位

    (取class的内容)

    driver.find_element_by_class_name("android.widget.RelativeLayout")

    • 通过xpath定位

    (取xpath得内容)

    driver.find_element_by_xpath("//android.widget.LinearLayout[1]/android.widget.XXX")

    • 通过text定位

    (需要使用uiautomator的定位方式,使用text的内容)

    driver.find_elements_by_android_uiautomator("new UiSelector().text("+关注")")

    使用这里需要注意一下,通过text定位的结果是个list,不能直接click。所以如果要点击需要取数组的值,比如下面是点击找到的第一个元素

    driver.find_elements_by_android_uiautomator("new UiSelector().text("+关注")")[0].click()

    • 通过css_selector定位(webview)

    只适用于webview的html页面,继承自webdriver,与pc版本的UI测试一致

    driver.find_element_by_css_selector()

    • 通过link_text定位(webview)

    只适用于webview容器中的html页面,继承自webdriver,与pc版本的UI测试一致

    driver.find_element_by_link_text()

    • 通过name定位

    web view容器中的html页面可以用name定位,native并没有name属性

    driver.find_element_by_name()

    2.定位元素的另一种写法:find_element(by,value)

    find_element_by_方式(value)实际调用的都是find_element(by,value)

    需要导入这个包:from selenium.webdriver.common.by import By

    例如:定位id为ag2的元素

    方式一:driver.find_element_by_id("ag2”)
    方式二:driver.find_element(By.ID,"ag2")

    这个操作的好处是可以直接把操作的by和value放到一个元组里,然后调用通用方法来传参获得元素结果

    cateid=(By.ID,"ag2")
    
    driver.find_element(*cateid).click()

    by的操作可以是:

    By.ID   相当于by_id
    By.CLASS_NAME  相当于by_class_name
    By.XPATH   相当于by_xpath
    By.NAME   相当于by_name
    By.TAG_NAME   相当于by_tag_name
    By.CSS_SELECTOR  相当于by_css_selector
    By.LINK_TEXT  相当于by_link_text

    3.find_elements_by_定位方式(value)返回元素数组

    用法与find_element_by_方式(value)一致,但是返回一个数组。可以通过数组的索引来访问具体的某个结果

    例如:通过class_name定位到多个元素,我想点击第一个元素

    driver.find_elements_by_class_name("android.widget.RelativeLayout”)[0].click()

    4.返回元素数组的另一种写法:find_elements(by,value)

    用法与find_element(by,value)一致,但是返回一个数组。可以通过数组的索引来访问具体的某个结果

    例如:通过class_name定位到多个元素,我想点击第一个元素

    driver.find_elements(By.CLASS_NAME,"android.widget.RelativeLayout”)[0].click()

    5.通过元素定位元素

    可以先找到某个元素,然后再进一步定位元素

    find_element_by_class_xpath(“xxx”).find_element_by_name(“yyy") 

    三、元素操作

    找到元素后可以对元素进行的操作,例如上面讲的进一步定位元素

    • 1.click()

    //点击操作

    也可以用tab实现点击操作

    driver.find_element_by_id("com.wuba.zhuanzhuan:id/ae8").click()

    • 2.clear()

    //清空输入框内容

    driver.find_element_by_id("com.wuba.zhuanzhuan:id/ij").clear()

    • 3.send(xx)

    //输入框内输入内容

    driver.find_element_by_id("com.wuba.zhuanzhuan:id/ij").send_keys("test content")

    • 4.text

    //获得元素的text内容

    print(driver.find_element_by_xpath(" //android.widget.LinearLayout[1]//xxx").text)

    四、触摸操作

    1.driver.tap([坐标],持续点击时间)

    除了定位到元素的点击外,也可以通过tab实现坐标的点击

    driver.tap(driver.tap([(216,1776)],2))

    2.TouchAction(driver)

    TouchAction对象包含(tab)、press(短按)、move_to(滑动到某个坐标)等方法

    通过TouchAction对象,添加tap、move_to等操作,然后perform()执行,可以实现解锁屏幕等功能

    规范中的可用事件有:

     * 短按 (press)
     * 释放 (release)
     * 移动到 (moveTo)
     * 点击 (tap)
     * 等待 (wait)
     * 长按 (longPress)
     * 取消 (cancel)
     * 执行 (perform)

    例如:一个多次滑屏的例子:

    action=TouchAction(driver)
    action.press(x=220,y=700).move_to(x=840, y=700).move_to(x=220, y=1530).move_to(x=840, y=1530).release().perform()

    可以通过wait()等待操作

    3.MultiAction()//多点触控

    通过MultiAction().add()添加多个TouchAction操作,最后调用perform()一起执行这些操作

    action0 = TouchAction().tap(el)

    action1 = TouchAction().tap(el)

    MultiAction().add(action0).add(action1).perform()

    4.driver.swipe(x1, y1, x2, y2,duration)  

    //从坐标(x1,x2)滑动到坐标(x2,y2),duration非必填项,滑动时间

    (滑动的坐标不能超过屏幕的宽高)

    可以通过【driver.get_window_size()】命令获得窗口高和宽,结果为{'width': 1080, 'height': 1776}

    一个鼠标向上下左右活动的例子如下:

    # 获得屏幕大小宽和高
    def getSize(driver):
        x = driver.get_window_size()['width']
        y = driver.get_window_size()['height']
        return (x, y)
    
    # 屏幕向上滑动
    def swipeUp(driver,t=1000):
        l = getSize(driver)
        x1 = int(l[0] * 0.5)    #x坐标
        y1 = int(l[1] * 0.75)   #起始y坐标
        y2 = int(l[1] * 0.25)   #终点y坐标
        driver.swipe(x1, y1, x1, y2,t)
    
    # 屏幕向下滑动
    def swipeDown(driver,t=1000):
        l = getSize(driver)
        x1 = int(l[0] * 0.5)  #x坐标
        y1 = int(l[1] * 0.25)   #起始y坐标
        y2 = int(l[1] * 0.75)   #终点y坐标
        driver.swipe(x1, y1, x1, y2,t)
    
    # 屏幕向左滑动
    def swipLeft(driver,t):
        l=getSize(driver)
        x1=int(l[0]*0.75)
        y1=int(l[1]*0.5)
        x2=int(l[0]*0.05)
        driver.swipe(x1,y1,x2,y1,t)
    
    # 屏幕向右滑动
    def swipRight(driver,t=1000):
        l=getSize(driver)
        x1=int(l[0]*0.05)
        y1=int(l[1]*0.5)
        x2=int(l[0]*0.75)
        driver.swipe(x1,y1,x2,y1,t)
    
     # 调用向下滑动的方法
     swipeDown(driver)

    五、系统按键事件

    press_keycode(AndroidKeyCode)//发送按键事件

    例如:点击home键,home键的KeyCode是3

    driver.press_keycode(3)

          键名                      描述            键值
    KEYCODE_CALL                  拨号键             5
    KEYCODE_ENDCALL               挂机键             6
    KEYCODE_HOME                  按键Home          3
    KEYCODE_MENU                  菜单键             82
    KEYCODE_BACK                  返回键             4
    KEYCODE_SEARCH                搜索键             84
    KEYCODE_CAMERA                拍照键             27
    KEYCODE_FOCUS                 拍照对焦键          80
    KEYCODE_POWER                 电源键             26
    KEYCODE_NOTIFICATION          通知键             83
    KEYCODE_MUTE                  话筒静音键          91
    KEYCODE_VOLUME_MUTE           扬声器静音键        164
    KEYCODE_VOLUME_UP             音量增加键          24
    KEYCODE_VOLUME_DOWN           音量减小键          25                                    

    更多KeyCode可以查看下面的博客:

    http://blog.csdn.net/crisschan/article/details/50419963

    六、driver的一些比较重要操作

    1.reset()

    //重置app

    这时候driver会重置,相当于卸载重装应用。所以本地缓存会失效

    driver.reset()

    2.start_activity(包名,activity名)

    //启动app的某一个activity

    例如:driver.start_activity("com.wuba.zhuanzhuan","./presentation.view.activity.LaunchActivity")

    启动一个activity,这个activity必须是AndroidManifest.xml中有intent-filter的activity

    <intent-filter>

        <action android:name="android.intent.action.MAIN"/>

       <category android:name="android.intent.category.LAUNCHER"/>

    </intent-filter>

    这种启动activity和driver的reset()不同的是

    3.contexts

    //获得所有contexts

    driver.contexts

    结果如下:

    ['NATIVE_APP', 'WEBVIEW_com.android.browser']

    NATIVE_APP:native的context

    WEBVIEW_com.android.browser:webview的context,存放html的容器

    4.current_context

    //查看当前的context

    driver.current_context

    5.switch_to.context(context名)

    //切换context

    driver.switch_to.context("WEBVIEW_com.wuba.zhuanzhuan")

    NATIVE时不能定位WEBVIEW的内容,在WEBVIEW的context时不能定位NATIVE的内容。

    所以需要切换到对应的context中去进行操作

    6.setNetworkConnection(bitmask掩码)

    //设置网络类型

    例如:设置网络类型为只开wifi

    driver.set_network_connection(2)

    网络的bitmask掩码如下:

    | 值 (别名)           | 数据连接 | Wifi 连接 | 飞行模式 |

    | ------------------ | ---- | ---- | ------------- |

    | 0 (什么都没有)       | 0    | 0    | 0 |

    | 1 (飞行模式)         | 0    | 0    | 1 |

    | 2 (只有Wifi)        | 0    | 1    | 0 |

    | 4 (只有数据连接)     | 1    | 0    | 0 |

    | 6 (开启所有网络)     | 1    | 1    | 0 |

    7.scroll(起始元素,结束元素)

    driver.scroll(origin_el,destination_el)

    8.获得当前页面的所有元素

    driver.page_source

    这可以用来判断元素是否存在,例如(assert "发布成功" in driver.page_source)

    9.补充一些driver启动时可能用到的项

    其实这些在上一篇启动里都有介绍,但是有些可能大家没注意到的点再列一下。这些点也是我在测试中实际遇到的点

    autoLaunch :Appium是否要自动启动或安装app,默认true

    desired_caps['autoLaunch'] = 'false'

    有的时候我不想让appium每次都启动app,想自己去启动activity,那这个项这时就可以起作用了

    noReset:在会话前是否重置app状态。默认是false

    desired_caps['noReset'] = 'true'

    newCommandTimeout:设置未接收到新命令的超时时间,默认60s

    如果60s内没有接收到新命令,appium会自动断开连接,如果我需要很长时间做driver之外的操作,可能延长接收新命令的超时时间

    desired_caps["newCommandTimeout"]=1800

  • 相关阅读:
    Appium + Python自动化
    Appium + python自动化
    基于python的request库,模拟登录csdn博客
    利用uiautomator实现Android移动app启动时间的测试
    JavaScript 闭包
    Vue.js 参考资料汇总
    JVM垃圾回收策略
    JVM内存分配策略
    synchronized底层原理
    HTTPS加密原理
  • 原文地址:https://www.cnblogs.com/yitao326/p/13718618.html
Copyright © 2011-2022 走看看