• Airtest API精讲之Android自定义手势


    上期回顾:Airtest API精讲之放大缩小pinch()


    以下基于
    python3.8;airtestIDE1.2.11;airtest1.2.2;pocoui1.0.83

    老规矩开场白,我们今天要讲的是Airtest框架的内容,不是Poco框架的,一般我们说Airtest,其实应该指的是Airtest Project,具体这些概念的关系是什么,可以看之前文章:Airtest Project——UI自动化利器介绍

    之前我们已经陆续讲了:
    Airtest API精讲之swipe()
    Airtest API精讲之连续滑动swipe_along()
    Airtest API精讲之双指滑动two_finger_swipe()
    Airtest API精讲之放大缩小pinch()

    归根结底,这些都是定义好的一些手势操作。如果你看了之前的源码解析,应该知道其实实现以上手势的基础在底层就是模拟手指按下、滑动、延时、抬起操作。如果你之前玩过按键精灵,相信会更容易理解,原理是一样的。

    但是,以上这些操作,在面对一些复杂业务的时候,可能无法实现一些操作,比如MIUI中删除APP,如果你先long_click()长按应用图标,再swipe()到顶部删除图标,中间是会断的。因为long_click()的完整执行过程是按下、延时、抬起,此时再swipe(),因为前面已经抬起,导致删除操作接不上。

    再比如MIUI中三指下滑的截图操作,之前的API最多是两指同时操作,不支持三指。

    好在Airtest对Android支持自定义手势操作,允许你自己定义一系列操作并执行。


    在开始讲自定义手势之前,有必要了解一下其目录结构。还记得之前Airtest的目录结构吗?Airtest框架源码目录结构解析
    在your_python_path/core/android/touch_methods/目录下,一共有base_touch、minitouch、maxtouch、touch_proxy四个py文件。

    base_touch.py中有BaseTouch类,我们之前讲的4个API均是在这个类中定义。另外有DownEvent、UpEvent、MoveEvent、SleepEvent四个基础类,这四个类共同组成了之前4个API的基础操作。

    minitouch.py和maxtouch.py分别有Minitouch和Maxtouch类,其均是继承自BaseTouch类。当你的设备支持openstf的minitouch时则使用minitouch,否则使用maxtouch。maxtouch是Airtest自己开发的。其实这里的结构和Airtest源码分析--Android屏幕截图方式 是非常类似的。

    touch_proxy.py中定义了TouchProxy类,它会根据需要自动调用minitouch或maxtouch,所以对于上层是透明的,你不需要关心你用的是minitouch还是maxtouch,你直接执行minitouch或maxtouch中的方法就可以了。

    源码解析

    我们先来看下DownEvent、UpEvent、MoveEvent、SleepEvent四个基础类的源码(不想看源码的可以直接跳到后面的演示实例):

     1# 文件位置:your_python_path/site-packages/airtest/core/android/touch_methods/base_touch.py
    2# 以DownEvent为例
    3
    4class DownEvent(MotionEvent):
    5    def __init__(self, coordinates, contact=0, pressure=50):
    6        """
    7        Finger Down Event
    8        :param coordinates: finger down coordinates in (x, y)
    9        :param contact: multi-touch action, starts from 0
    10        :param pressure: touch pressure
    11        """
    12        super(DownEvent, self).__init__()
    13        self.coordinates = coordinates
    14        self.contact = contact
    15        self.pressure = pressure
    16
    17    def getcmd(self, transform=None):
    18        if transform:
    19            x, y = transform(*self.coordinates)
    20        else:
    21            x, y = self.coordinates
    22        cmd = "d {contact} {x} {y} {pressure}\nc\n".format(contact=self.contact, x=x, y=y, pressure=self.pressure)
    23        return cmd

    参数:
    coordinates:操作的绝对坐标点
    contact:   第X根手指,0是第1根手指(默认值),1是第2根手指……
    pressure:  按压力度,默认50

    每个类中的getcmd()方法返回了minitouch的协议命令。其中contact为手指的意思,就是第几根手指,pressure是按压强度(默认50),填入完整参数后的一个协议示例,手指0在[100,0]以力道50按下:

    1d 0 100 0 50
    2c

    我们要实现自定义的操作,也是像官方提供的4个API一样,去组合这4个基础操作,比如删除APP的操作,就是DownEvent按下+SleepEvent延时几秒+MoveEvent移到删除图标+UpEvent抬起。把这些操作按顺序放入列表,并使用perform()执行。

    我们再看下perform()源码:

     1# 文件位置:your_python_path/site-packages/airtest/core/android/touch_methods/base_touch.py
    2    def perform(self, motion_events, interval=0.01):
    3        """
    4        Perform a sequence of motion events including: UpEvent, DownEvent, MoveEvent, SleepEvent
    5
    6        Args:
    7            motion_events: a list of MotionEvent instances
    8            interval: minimum interval between events
    9
    10        Returns:
    11            None
    12        """
    13        for event in motion_events:
    14            if isinstance(event, SleepEvent):
    15                time.sleep(event.seconds)
    16            else:
    17                cmd = event.getcmd(transform=self.transform_xy)
    18                self.handle(cmd)
    19                time.sleep(interval)

    参数:
    motion_events:操作列表
    interval:    操作间隔,默认0.01秒

    大致逻辑就是循环判断传入的事件列表,如果是SleepEvent类就等待相应时间,否则就执行具体类中的getcmd()方法。

    演示实例

    删除APP自定义手势

     1# -*- encoding=utf8 -*-
    2__author__ = "测试工程师小站"
    3
    4from airtest.core.api import *
    5from airtest.core.android.touch_methods.base_touch import *
    6
    7# 获取当前手机设备
    8dev = device()
    9
    10# 定义操作事件列表
    11delete_app_event = [
    12    DownEvent([908, 892]),  # 在应用的坐标上按下手指
    13    SleepEvent(2),  # 延时2秒
    14    MoveEvent([391, 523]),  # 移动到中间点
    15    SleepEvent(0.5),
    16    MoveEvent([165,285]),  # 移动到删除应用的垃圾桶坐标
    17    SleepEvent(2),  # 延时2秒
    18    UpEvent()  # 抬起手指
    19    ]
    20
    21# 执行操作事件列表
    22dev.touch_proxy.perform(delete_app_event)
    23
    24# 执行完删除APP手势后,再执行一个点击操作点确定即可,这里不再写出

    图片

    三指滑屏截图自定义手势

     1# -*- encoding=utf8 -*-
    2__author__ = "测试工程师小站"
    3
    4from airtest.core.api import *
    5from airtest.core.android.touch_methods.base_touch import *
    6
    7# 获取当前手机设备
    8dev = device()
    9
    10# 定义三指起始点
    11finger1, finger2, finger3 = [228, 388],[528, 388],[828, 388]
    12
    13# 定义操作事件列表
    14snapshot_event = [
    15    DownEvent(finger1, 0),  # 按下手指1
    16    DownEvent(finger2, 1),  # 按下手指2
    17    DownEvent(finger3, 2),  # 按下手指3
    18    SleepEvent(0.1),  # 延时0.1秒
    19    ]
    20
    21# 我们模拟三根手指滑动3次后到手机底部
    22for i in range(1,4):
    23    node1 = [finger1[0],finger1[1]+500*i]  # 定义手指1滑动节点
    24    node2 = [finger2[0],finger3[1]+500*i]  # 定义手指2滑动节点
    25    node3 = [finger2[0],finger3[1]+500*i]  # 定义手指3滑动节点
    26    snapshot_event.append(MoveEvent(node1, 0))# 手指1滑动到node1
    27    snapshot_event.append(MoveEvent(node2, 1))# 手指2滑动到node2
    28    snapshot_event.append(MoveEvent(node3, 2))# 手指3滑动到node3
    29    snapshot_event.append(SleepEvent(0.2))  # 延时0.2秒
    30
    31# 加入三根手指的抬起事件
    32snapshot_event.append(UpEvent(0))
    33snapshot_event.append(UpEvent(1))
    34snapshot_event.append(UpEvent(2))
    35
    36# 执行操作事件列表
    37dev.touch_proxy.perform(snapshot_event)

    图片

    ---------------------------------------------------------------------------------

    关注微信公众号即可在手机上查阅,并可接收更多测试分享~

  • 相关阅读:
    「LibreOJ NOI Round #2」不等关系
    Atcoder Grand Contest 036 D
    「CTS2019」氪金手游
    「CTS2019」珍珠
    「APIO2016」烟花表演
    「PKUWC2018/PKUSC2018」试题选做
    「PKUWC2018」猎人杀
    「WC 2019」数树
    CodeForces 794 G.Replace All
    「BZOJ 4228」Tibbar的后花园
  • 原文地址:https://www.cnblogs.com/songzhenhua/p/15612615.html
Copyright © 2020-2023  润新知