Airtest API精講之連續滑動swipe_along()

上期回顧:Airtest API精講之swipe()

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

上期我們講了swipe(),可以從一個圖片或座標滑動到另一個圖片或座標,簡單講就是一個點到另一個點的滑動,那麼多個點的滑動怎麼操作呢?最典型的就是9宮格解鎖,可以通過swipe_along()來實現。

老規矩開場白,我們今天要講的是Airtest框架的swipe_along(),不是Poco框架的,一般我們說Airtest,其實應該指的是Airtest Project,具體這些概念的關係是什麼,可以看之前文章:Airtest Project——UI自動化利器介紹

首先說明一點,某些模擬器如果你選擇的連接參數中有"Use Adb Touch",可能將無法使用swipe_along(),不行就換真機吧。

源碼解析

我們先來看下swipe_along()的源碼(不想看源碼的可以直接跳到後面的演示實例):

 1# 文件位置:your_python_path/site-packages/airtest/core/android/touch_methods/base_touch.py
2
3    def swipe_along(self, coordinates_list, duration=0.8, steps=5):
4        """
5        Perform swipe event across multiple points in sequence.
6
7        Args:
8            coordinates_list: list of coordinates: [(x1, y1), (x2, y2), (x3, y3)]
9            duration: time interval for swipe duration, default is 0.8
10            steps: size of swipe step, default is 5
11
12        Returns:
13            None
14
15        """
16        tuple_from_xy = coordinates_list[0]
17        swipe_events = [DownEvent(tuple_from_xy, pressure=self.default_pressure), SleepEvent(0.1)]
18        for tuple_to_xy in coordinates_list[1:]:
19            swipe_events += self.__swipe_move(tuple_from_xy, tuple_to_xy, duration=duration, steps=steps)
20            tuple_from_xy = tuple_to_xy
21
22        swipe_events.append(UpEvent())
23        self.perform(swipe_events)

參數:
coordinates_list:座標列表,如[[10,20],[20,20],[30,20]]
duration:執行每2個點之間的等待時間,默認0.8秒
steps:執行每2個點之間的運行步數,默認5

第16行tuple_from_xy = coordinates_list[0]將座標列表中的第一個座標賦值給tuple_from_xy,意爲起點

第17行:

swipe_events = [DownEvent(tuple_from_xy, pressure=self.default_pressure), SleepEvent(0.1)]

定義了一個滑動事件列表swipe_events,並向列表中加入了2個事件:起點的按下事件,0.1秒的等待事件

第18-20行,從座標列表的第2個座標開始,循環給滑動事件列表swipe_events追加每2個相臨座標之間的移動事件

第22行swipe_events.append(UpEvent())給滑動事件列表swipe_events追加一個擡起事件

第23行self.perform(swipe_events)將滑動事件列表中的每個事件依次執行


 

再來看下swipe_along()第19行中self.__swipe_move()移動事件的詳細實現:

 1# 文件位置:your_python_path/site-packages/airtest/core/android/touch_methods/base_touch.py
2    def __swipe_move(self, tuple_from_xy, tuple_to_xy, duration=0.8, steps=5):
3        """
4        Return a sequence of swipe motion events (only MoveEvent)
5
6        minitouch protocol example::
7
8            d 0 0 0 50
9            c
10            m 0 20 0 50
11            c
12            m 0 40 0 50
13            c
14            m 0 60 0 50
15            c
16            m 0 80 0 50
17            c
18            m 0 100 0 50
19            c
20            u 0
21            c
22
23        Args:
24            tuple_from_xy: start point
25            tuple_to_xy: end point
26            duration: time interval for swipe duration, default is 0.8
27            steps: size of swipe step, default is 5
28
29        Returns:
30            [MoveEvent(from_x, from_y), ..., MoveEvent(to_x, to_y)]
31        """
32        from_x, from_y = tuple_from_xy
33        to_x, to_y = tuple_to_xy
34
35        ret = []
36        interval = float(duration) / (steps + 1)
37
38        for i in range(1, steps):
39            ret.append(MoveEvent((from_x + (to_x - from_x) * i / steps,
40                                  from_y + (to_y - from_y) * i / steps)))
41            ret.append(SleepEvent(interval))
42        ret += [MoveEvent((to_x, to_y), pressure=self.default_pressure), SleepEvent(interval)]
43        return ret

第36行interval = float(duration) / (steps + 1)2個座標之間的總等待時間/步數+1

第39行,因爲把2個座標分成了steps步,所以這裏相當於把2個座標之間的移動,又分成了steps-1次移動,將依次添加每一個小步的移動事件

第41行ret.append(SleepEvent(interval)),同上,因爲把2個座標之間的移動,又分了成steps-1次,所以等待時間也要均分,並添加均分後時間的等待事件

第42行,添加終點座標的滑動事件和等待事件

第43行return ret將整個移動事件列表返回


 

繼續看下swipe_along()第23行中self.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)

大致邏輯就是循環判斷滑動事件列表,如果是SleepEvent類就等待相應時間,否則就執行具體類中的getcmd()方法。
那除了SleepEvent類,通過上面幾個方法的源碼可以看到,還有DownEvent、UpEvent、MoveEvent三個類,每個類中的getcmd()方法返回了minitouch的協議命令,我們以DownEvent爲例看一下:

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

其中contact爲手指的意思,就是第幾根手指,pressure是按壓強度(默認50),填入完整參數後的一個協議示例,手指0在[100,0]以力道50按下:

1d 0 100 0 50
2c

 

演示實例

畫一個四邊形

先分別在手機上取四個點,不會的可以看之前的文章AirtestIDE基本功能(二)中的Device欄。
然後編寫腳本:

1# -*- encoding=utf8 -*-
2__author__ = "測試工程師小站"
3
4from airtest.core.api import *
5
6dev = device()  # 獲取當前手機設備
7# 依次滑過四個座標,每2個座標之間間隔3秒,分3小步
8dev.touch_proxy.swipe_along([[250, 819],[738, 824],[744, 1312],[248, 1312],[250, 819]], duration=3, steps=3)

我用的畫板App會自動處理爲圓角

圖片

可以看到每個邊是分爲3步,每一步間隔1秒,是不是對duration=3, steps=3這兩個參數有了直觀的理解。四邊形會畫了,圓形、三角形還是問題嗎?

解鎖九宮格

1# -*- encoding=utf8 -*-
2__author__ = "測試工程師小站"
3
4from airtest.core.api import *
5
6# 獲取當前手機設備
7dev = device()
8# 解鎖九宮格每一步沒必要再拆分,所以steps設爲1
9dev.touch_proxy.swipe_along([[246, 1186],[547, 1182],[537, 1470],[540, 1768],[835, 1772]], duration=1, steps=1)

 

圖片

 

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

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

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