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)

 

圖片

 

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

關注微信公衆號即可在手機上查閱,並可接收更多測試分享~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章