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)

 

图片

 

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

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

posted @ 2021-11-27 18:08  ☆星空物语☆  阅读(768)  评论(0编辑  收藏  举报