Poco API精講之 等待 wait

上期回顧:Poco API精講之元素屬性操作attr、setattr……


以下基於
python3.8;airtestIDE1.2.13;airtest1.2.4;pocoui1.0.85

注意:Poco框架和Airtest框架很多API是同名的,但使用方法完全不一樣!!!一定不要搞混了,我初學時也經常搞混,這點一定要注意!
具體Poco框架和Airtest框架是什麼關係,可以看之前文章:Airtest Project——UI自動化利器介紹

之前講了Poco元素定位與屬性,今天我們講下自動化測試中重要的一種操作——等待,自動化腳本健壯性好不好,關鍵看你等待用的好不好。Poco框架中一共有5種等待方法,分別是wait、wait_for_appearance、wait_for_disappearance、wait_for_any、wait_for_all,下面依次詳細看下各個方法怎麼用。

1.wait(timeout=3)

等待元素X秒。

參數:
timeout - 等待時間,默認3秒

返回:
自身

源碼解析:

# 源碼位置:your_python_path\site-packages\poco\proxy.py
    def wait(self, timeout=3):
        start = time.time()
        while not self.exists():
            self.poco.sleep_for_polling_interval()
            if time.time() - start > timeout:
                break
        return self

源碼的核心邏輯就是通過while循環,使用Poco框架的exists()方法判斷元素是否出現了。
如果出現了則不符合while循環條件退出循環;
如果沒出現,等待1.44秒(sleep_for_polling_interval就是等待固定1.44秒)後判斷是否達到超時時間,時間達到使用break強制退出循環。
最後不管等沒等到,都返回元素對象本身。

我們再來看下exists()的源碼,是怎麼判斷元素是否出現的。

# 源碼位置:your_python_path\site-packages\poco\proxy.py
        try:
            return self.attr('visible')
        except (PocoTargetRemovedException, PocoNoSuchNodeException):
            return False

很簡單,返回元素的'visible'屬性,如果元素出現了,其'visible'屬性將是True,即返回True。如果元素沒出現,因爲屬性不存在會報錯,所以放在try…except中,並返回False。

一定要注意Poco框架的wait()、exists()和Airtest框架的wait()、exists()是不一樣的。可以對比着看看:Airtest API精講之wait(),exists()

所以Poco框架的wait(),如果等到元素則提前返回;如果在設定時間內沒等到也會返回,不會報錯。另外wait()之所以返回元素對象本身,是爲了代碼可以接着寫方便。

示例:

from airtest.core.api import *
from poco.drivers.unity3d import UnityPoco

auto_setup(__file__)

poco = UnityPoco()

# 等待元素60秒,如果其出現則立馬點擊。
# 如果一直沒出現,則元素不存在,click會導致PocoNoSuchNodeException報錯
poco('測試工程師小站').wait(60).click()


# 等待元素3秒,如果其出現才點擊,避免了元素不存在,直接點擊導致的報錯
qa_button = poco('測試工程師小站')
if qa_button.wait():
    qa_button.click()

2.wait_for_appearance(timeout=120)

等待元素出現,等到提前結束,等不到報錯

參數:
timeout - 等待時間,默認120秒

返回:
None

異常:
PocoTargetTimeout:等待元素超時

源碼解析:

# 源碼位置:your_python_path\site-packages\poco\proxy.py
    def wait_for_appearance(self, timeout=120):
        start = time.time()
        while not self.exists():
            self.poco.sleep_for_polling_interval()
            if time.time() - start > timeout:
                raise PocoTargetTimeout('appearance', self)

通過源碼可以看出,wait_for_appearance()和wait()很像,就最後兩行代碼不一樣。區別就是wait_for_appearance()沒有返回,且如果沒等到元素,會報錯。具體使用上的區別看示例。

假設場景:
我們想點擊登陸按鈕,之後用例才能繼續進行,如果登陸不了,用例也就不用執行下去了。在點擊登陸按鈕之前,有50%機率會彈一個提醒,如果彈了提醒必須點掉,否則就點擊不到登陸了。

示例:

from airtest.core.api import *
from poco.drivers.unity3d import UnityPoco

auto_setup(__file__)

poco = UnityPoco()

tips = poco('提醒')
login = poco('測試工程師小站登陸')

# 這裏提醒只是機率出現,所以即使不出現,也是正常的,無需報錯
if tips.wait(10):  # 等待提醒框最多10秒
    tips.click()  #  如果提醒框出現則點掉,否則影響點擊登陸

# login的poco對象定義可以提前定義,定義不會執行
# 只有對象在進行操作時,纔會去真正查找,所以Poco適合PO模型
# 這裏如果找不到登陸按鈕,後面的用例流程也執行不了,所以要報錯退出
login.wait_for_appearance()  # 死等登陸120秒,不出現我就報錯
login.click()  # login如果出現了,就可以執行該行的點擊了

3.wait_for_disappearance(timeout=120)

等待元素消失,消失則提前結束,timeout秒仍未消失則報錯

參數:
timeout - 等待時間,默認120秒

返回:
None

異常:
PocoTargetTimeout:等待元素超時

源碼解析:

# 源碼位置:your_python_path\site-packages\poco\proxy.py
    def wait_for_disappearance(self, timeout=120):
        start = time.time()
        while self.exists():
            self.poco.sleep_for_polling_interval()
            if time.time() - start > timeout:
                raise PocoTargetTimeout('disappearance', self)

wait_for_disappearance的源碼就比wait_for_appearance源碼少了一個not,就不再多講了

4.wait_for_any(objects, timeout=120)

等待給定元素列表中任一元素出現,並返回該元素

參數:
objects - 元素列表
timeout - 等待時間

返回:
出現的UIObjectProxy實例

異常:
PocoTargetTimeout:等待元素超時

源碼解析:

# 源碼位置:your_python_path\site-packages\poco\pocofw.py
    def wait_for_any(self, objects, timeout=120):
        start = time.time()
        while True:
            for obj in objects:
                if obj.exists():
                    return obj
            if time.time() - start > timeout:
                raise PocoTargetTimeout('any to appear', objects)
            self.sleep_for_polling_interval()

等待的源碼都是差不多的,wait_for_any就是用了一個for循環去遍歷看元素列表中的元素是否有一個出現,只要有1個出現,就立馬返回該元素。如果超時了一個沒出現,就報錯了。

示例:

from airtest.core.api import *
from poco.drivers.unity3d import UnityPoco

auto_setup(__file__)

poco = UnityPoco()

# 屏幕上會隨機出現1元、10元、100元,點了就是你的!
# 那妥了,不管出現多少錢,我都點啊,不要白不要,要了還想要!
m1 = poco('monkey1')
m10 = poco('monkey10')
m100 = poco('monkey100')
# 如果1元出現,monkey對象就是1元,如果10元出現,monkey對象就是10元...
monkey = wait_for_any([m1,m10,m100])
monkey.click()

5.wait_for_all(objects, timeout=120)

等待所有元素出現

參數:
objects - 元素列表
timeout - 等待時間

返回:
None

異常:
PocoTargetTimeout:等待元素超時

源碼解析:

# 源碼位置:your_python_path\site-packages\poco\pocofw.py
    def wait_for_all(self, objects, timeout=120):
        start = time.time()
        while True:
            all_exist = True
            for obj in objects:
                if not obj.exists():
                    all_exist = False
                    break
            if all_exist:
                return
            if time.time() - start > timeout:
                raise PocoTargetTimeout('all to appear', objects)
            self.sleep_for_polling_interval()

核心就是通過for循環去判斷元素列表中元素是否都出現了,如果都出現了則返回;如果有一個沒出現,就接着找,直到超時報錯。
其中while內的前5行代碼有一個隱藏的邏輯,就是每次遍歷查找所有元素,必須都在了纔行。如果第1輪查找,元素1在,元素2沒在,第2輪時元素1要重新確認在,防止元素1又消失了。

示例:

from airtest.core.api import *
from poco.drivers.unity3d import UnityPoco

auto_setup(__file__)

poco = UnityPoco()

# 這次規則變了,屏幕上會隨機出現1元、10元、100元,但只有1次點擊收取按鈕的機會
# 爲了利益最大化,所以要等所有錢全出現了,再點擊收取按鈕
m1 = poco('monkey1')
m10 = poco('monkey10')
m100 = poco('monkey100')
get = poco('收取')

wait_for_all([m1,m10,m100])  # 等1元、10元、100元全出現
get.click()

好了,以上就是Poco的5種等待,你學廢了嗎:)

 

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

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

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