zoukankan      html  css  js  c++  java
  • Android自动化学习5--对uiautomator2常用操作进行封装

    前言

    本次我们将会对 uiautomator2 的一些基本操作进行简单的封装,以便更好的应用到UI自动化中。

    重复多次滑动

    在 uiautomator2 中,给我们提供了一些滑动的操作 swipe(),以及滑动扩展的操作 swipe_ext(),基于此我们可以对重复多次的滑动操作进行简单封装。

        def up(self, scale=0.9, times=1, duration=1.0, **kwargs):
            """
            上滑操作
            :param scale: 滑动单位,默认0.9个单位
            :param times: 滑动次数,默认1次
            :param duration: 滑动时间,默认1.0秒
            :return:
            """
            for i in range(times):
                self.d.swipe_ext("up", scale, duration=duration, **kwargs)
    
        def down(self, scale=0.9, times=1, duration=1.0, **kwargs):
            """
            下滑操作
            :param scale: 滑动单位,默认0.9个单位
            :param times: 滑动次数,默认1次
            :param duration: 滑动时间,默认1.0秒
            :return:
            """
            for i in range(times):
                self.d.swipe_ext("down", scale, duration=duration, **kwargs)
    
        def left(self, scale=0.9, times=1, duration=1.0, **kwargs):
            """
            左滑操作
            :param scale: 滑动单位,默认0.9个单位
            :param times: 滑动次数,默认1次
            :param duration: 滑动时间,默认1.0秒
            :return:
            """
            for i in range(times):
                self.d.swipe_ext("left", scale, duration=duration, **kwargs)
    
        def right(self, scale=0.9, times=1, duration=1.0, **kwargs):
            """
            右滑操作
            :param scale: 滑动单位,默认0.9个单位
            :param times: 滑动次数,默认1次
            :param duration: 滑动时间,默认1.0秒
            :return:
            """
            for i in range(times):
                self.d.swipe_ext("right", scale, duration=duration, **kwargs)
    

    间隔等待元素

    我们在做UI自动化时,如果需要在进入某个APP页面后点击元素,那么一般先会等待一段时间,然后再进行点击操作,但是在这个过程中,到底等待多长时间才比较合适,这个就不太好判断。

    因此,我们可以用另一种思路来实现:

    • 检查定位元素是否存在
    • 如果定位失败就间隔一段时间后重试
    • 循环以上操作,直到元素定位成功就点击,或超时抛出异常
        def wait_until_element_found(self, param, timeout=30.0, retry_interval=2, wait_after_found=0.0):
            """
            定位元素,如果不存在就间隔若干秒后重试,直到元素定位成功或超时
            :param param: xpath字符串 或 元素对象
            :param timeout: 超时, 默认30秒
            :param retry_interval: 间隔时间, 默认2秒
            :param wait_after_found: 找到元素后,原地等待时间
            :return:
            """
            element = self.d.xpath(param) if isinstance(param, str) else param
            max_time = time.time() + timeout
            while True:
                try:
                    assert element.exists
                    if wait_after_found:
                        print("Element found,then sleep {} seconds".format(wait_after_found))
                    time.sleep(wait_after_found)
                    return element
                except AssertionError:
                    param = param if isinstance(param, str) else param.selector
                    print("Element 【 {} 】 Not found, Retry...".format(param))
                    if time.time() > max_time > 0:
                        raise AssertionError("Element 【 {} 】 located failed after {} timeout".format(param, timeout))
                    time.sleep(retry_interval)
    
        def wait_for_click(self, param, wait_after_click=0.0, **kwargs):
            """
            判断UI元素是否存在, 不存在则等待UI元素在一定时间内出现,再进行点击
            :param param: xpath字符串 或 元素对象
            :param wait_after_click: 点击后等待时间
            :return:
            """
            element = self.wait_until_element_found(param, **kwargs)
            element.click()
            if wait_after_click:
                print("Element found and click,then sleep {} seconds".format(wait_after_click))
            time.sleep(wait_after_click)
    

    重复多次点击

    在 uiautomator2 中,给我们提供了一些点击的操作,如 单击click(),双击double_click(),长按long_click() 等,基于此我们可以对重复多次的点击操作进行简单封装。

        def repeat_click(self, param, times, wait_after_repeat_click=0.0):
            """
            重复多次点击UI元素
            :param param: xpath字符串 或 元素对象
            :param times: 点击次数
            :param wait_after_repeat_click: 重复点击后等待时间,默认为0.0
            :return:
            """
            element = self.wait_until_element_found(param)
            for i in range(times):
                element.click()
            if wait_after_repeat_click:
                print("Element click,then sleep {} seconds".format(wait_after_repeat_click))
            time.sleep(wait_after_repeat_click)
    

    滑动查找元素

    我们在做UI自动化时,有时需要进行多次上滑操作,比如我进入某个APP页面,需要定位是否某个元素,而这个元素可能位于页面中间部分,也可能位于页面最底部,需滑到页面底部时才出现,又或者页面上不存在该元素,在整个过程中,我们需在滑动的过程中对元素进行定位。

    因此,我们可以用以下思路来实现:

    • 检查定位元素是否存在
    • 如果定位失败就进行一次滑动,滑动后重试
    • 循环以上操作,直到滑动到页面底部,若该过程中元素定位成功就点击
        def swipe_until_element_found(self, param, wait_after_found=0.0, **kwargs):
            """
            检查元素是否存在,若不存在则进行上滑,滑动后再次检查,直到滑动到页面底部
            若找到元素则返回,否则滑动到页面底部后,仍未找到元素,则抛出异常,提示找不到元素
            :param param: xpath字符串 或 元素对象
            :param wait_after_found: 找到元素后,原地等待时间
            :param kwargs:
            :return:
            """
            element = self.d.xpath(param) if isinstance(param, str) else param
            param = param if isinstance(param, str) else param.selector
            while True:
                try:
                    assert element.exists
                    if wait_after_found:
                        print("Element found,sleep {} seconds".format(wait_after_found))
                    time.sleep(wait_after_found)
                    return element
                except AssertionError:
                    print("Element 【 {} 】 Not found, Continue to swipe up...".format(param))
                    # 获取滑动前页面下半部分的所有元素
                    page_content = self.d.dump_hierarchy()[(len(self.d.dump_hierarchy()) // 2):]
                    self.up(**kwargs)
                    time.sleep(0.5)
                    # 获取滑动后页面下半部分的所有元素,并与上一次滑动前的页面元素对比,页面元素没有变化时跳出循环
                    if self.d.dump_hierarchy()[(len(self.d.dump_hierarchy()) // 2):] == page_content:
                        break
            if not element.exists:
                raise AssertionError("Element 【 {} 】 located failed in this page".format(param))
    
        def swipe_for_click(self, param, wait_after_click=0.0, **kwargs):
            """
            判断UI元素是否存在, 不存在则持续向上滑动到底部,直到UI元素在页面内出现,再进行点击
            :param param: xpath字符串 或 元素对象
            :param wait_after_click: 点击后等待时间
            :return:
            """
            element = self.swipe_until_element_found(param, **kwargs)
            element.click()
            if wait_after_click:
                print("Element found and click,then sleep {} seconds".format(wait_after_click))
            time.sleep(wait_after_click)
    
    作者:wintest
    本文版权归作者和博客园共有,欢迎转载,但必须在文章页面明显位置给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    像Google Play一样让DrawerLayout拉出的抽屉在透明系统状态栏和工具栏(ToolBar)之间。
    WebView中实现延迟加载,图片点击时才加载。
    MediaPlayer配合SurfaceView或TextureView做视频播放器时的截图方法。
    解决Fragment中使用ViewPager时,ViewPager里的Fragment错位和空白问题。
    使用SAE的Storage来为Android应用提供版本更新的检查和下载功能
    使用SAE的服务来实现android端的用户反馈功能。
    使用IntentService给自己的Android应用写一个文件下载器。
    禁止进入Activity时NumberPicker自动弹出输入法。
    使用Android系统提供的DownloadManager来下载文件。
    Android异步下载图片的类和缓存图片到SD卡的类。
  • 原文地址:https://www.cnblogs.com/wintest/p/14827229.html
Copyright © 2011-2022 走看看