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种等待,你学废了吗:)
---------------------------------------------------------------------------------
关注微信公众号即可在手机上查阅,并可接收更多测试分享~