上期回顧:Airtest API精講之Android自定義手勢
以下基於
python3.8;airtestIDE1.2.11;airtest1.2.2;pocoui1.0.83
老規矩開場白,我們今天要講的是Airtest框架的pinch(),不是Poco框架的,一般我們說Airtest,其實應該指的是Airtest Project,具體這些概念的關係是什麼,可以看之前文章:Airtest Project——UI自動化利器介紹
wait()和exists()有什麼區別?
相同點:
-
都是傳入一張圖片(template實例),然後判斷圖片是否存在;
-
如果圖片存在,兩者均會返回圖片座標。
不同點:
-
wait()找不到圖片會報錯TargetNotFoundError,而exists()找不到則返回False。
-
wait()默認查找時間是20秒,並可以指定查找時間;而exists()默認查找時間是3秒,不能指定查找時間。
-
兩者的查找間隔都是0.5秒,但wait()可以自定義時間,而exists()不行。
-
wait()有一個參數intervalfunc,可以在每輪未找到目標時,運行一個指定方法。
wait()
源碼解析
我們先來看下wait()的源碼(不想看源碼的可以直接跳到後面的演示實例):
1# 文件位置:your_python_path/site-packages/airtest/core/api.py
2def wait(v, timeout=None, interval=0.5, intervalfunc=None):
3 timeout = timeout or ST.FIND_TIMEOUT
4 pos = loop_find(v, timeout=timeout, interval=interval, intervalfunc=intervalfunc)
5 return pos
參數:
v – 要等待出現的目標Template實例
timeout – 等待匹配的最大超時時長,默認爲None即默認取 ST.FIND_TIMEOUT 的值20秒
interval – 嘗試查找匹配項的時間間隔(以秒爲單位),默認0.5秒
intervalfunc – 每輪查找匹配失敗後的回調函數
源碼解析:
第3行,指定了timeout則使用timeout;如果未指定timeout,值賦值爲ST.FIND_TIMEOUT,ST.FIND_TIMEOUT在your_python_path/site-packages/airtest/core/settings.py中,值爲20。
第4行,調用loop_find()循環查找方法。
第5行,返回座標。
我們看下loop_find()源碼
1# 文件位置:your_python_path/site-packages/airtest/core/cv.py
2def loop_find(query, timeout=ST.FIND_TIMEOUT, threshold=None, interval=0.5, intervalfunc=None):
3 G.LOGGING.info("Try finding: %s", query)
4 start_time = time.time()
5 while True:
6 screen = G.DEVICE.snapshot(filename=None, quality=ST.SNAPSHOT_QUALITY)
7
8 if screen is None:
9 G.LOGGING.warning("Screen is None, may be locked")
10 else:
11 if threshold:
12 query.threshold = threshold
13 match_pos = query.match_in(screen)
14 if match_pos:
15 try_log_screen(screen)
16 return match_pos
17
18 if intervalfunc is not None:
19 intervalfunc()
20
21 # 超時則raise,未超時則進行下次循環:
22 if (time.time() - start_time) > timeout:
23 try_log_screen(screen)
24 raise TargetNotFoundError('Picture %s not found in screen' % query)
25 else:
26 time.sleep(interval)
邏輯之前在Airtest源碼分析--圖像識別整體流程 講過,這裏重點說下中間的
1if intervalfunc is not None:
2 intervalfunc()
如果找到了,其上一句就返回座標了,所以走到這就是沒匹配到圖片。判斷intervalfunc是否爲None,如果不爲None,則運行intervalfunc()。所以wait()中的intervalfunc入參,其實是在這裏生效的。
演示實例
進入公衆號詳情,去匹配左上角的公衆號圖標,運行前先往上滑3屏。
這樣wait()中的循環的前2次是匹配不到圖標的,每次匹配不到時,執行函數not_find_fun(),即下滑。
最終匹配到時會返回圖標的座標,我把座標打印了出來,可以對比一下打印的座標和最後IDE中我鼠標指向圖標的座標是差不多的。
1# -*- encoding=utf8 -*-
2__author__ = "測試工程師小站"
3
4from airtest.core.api import *
5
6def not_find_fun():
7 """wait()循環查找時,每次未找到時執行的函數,即下滑"""
8 swipe([561, 512],[561, 1512])
9
10postion = wait(Template(r"tpl1635075246242.png", record_pos=(-0.369, -0.796), resolution=(1080, 2340)), timeout=30, interval=1, intervalfunc=not_find_fun)
11print(postion)
exists()
源碼解析
我們先來看下exists()的源碼(不想看源碼的可以直接跳到後面的演示實例):
1# 文件位置:your_python_path/site-packages/airtest/core/api.py
2def exists(v):
3 try:
4 pos = loop_find(v, timeout=ST.FIND_TIMEOUT_TMP)
5 except TargetNotFoundError:
6 return False
7 else:
8 return pos
參數:
v – 要等待出現的目標Template實例
源碼解析:
第4行,可以看到和wait()一樣,也是調用loop_find()循環查找方法。不過不同的是被包在try中,還記得上面loop_find()的源碼嗎,如果最終沒找到圖片,是會拋異常TargetNotFoundError。這裏專門針對TargetNotFoundError的報錯,當發生時不報錯並返回False。
演示實例
進入公衆號詳情,去匹配左上角的公衆號圖標,運行前先往上滑一屏。
這樣第一次exists()判斷圖標不存在,返回False;之後下滑。
第二次exists()判斷圖標存在,返回座標。
1# -*- encoding=utf8 -*-
2__author__ = "測試工程師小站"
3
4from airtest.core.api import *
5
6postion = exists(Template(r"tpl1635075246242.png", record_pos=(-0.369, -0.796), resolution=(1080, 2340)))
7print('*************************')
8print(postion)
9print('*************************')
10swipe([561, 512],[561, 1512])
11postion = exists(Template(r"tpl1635075246242.png", record_pos=(-0.369, -0.796), resolution=(1080, 2340)))
12print('*************************')
13print(postion)
14print('*************************')
---------------------------------------------------------------------------------
關注微信公衆號即可在手機上查閱,並可接收更多測試分享~