6.3强制等待、显式等待,隐式等待,重试循环

#按回车键页面更新了
        inputbox.send_keys(Keys.ENTER)
        time.sleep(1)
       self.check_for_row_in_list_table( "1:Buy woolen yarn")

我们看功能测试中的这段代码,这叫强制等待
强制等待,设置固定休眠时间。 python 的 time 包提供了休眠方法 sleep() , 导入 time 包后就可以使用 sleep(),进行脚本的执行过程进行休眠。

隐式等待相比强制等待更智能,在脚本中我们一般看不到等待语句,但是它会在每个页面加载的时候自动等待;隐式等待只需要声明一次,一般在打开浏览器后进行声明。声明之后对整个drvier的生命周期都有效,后面不用重复声明。
某些情况下,selenium 认为正在页面加载时,他会自动等待一会。如果页面查找的元素尚未出现,还可以使用implicitly_wait 指定等待多久

显式等待相比隐式等待更智能,是你定义的一段代码,用于等待某个条件发生然后再继续执行后续代码。
在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超过设置时间检测不到则抛出异常。默认检测频率为0.5s,默认抛出异常为:NoSuchElementException

我们在这个里使用了强制休眠1秒,但是我们不确定这是一个合理的时间啊,万一他0.1 秒就可以呢,但是如果设置0.1 秒又怕他等待的时间不够。所以说我们的sleep 太过含糊,
所以我们要调整我们的休眠的实现方式:
我们将check_for_row_in_list_table,重命名为wait_for_row_in_list_table,添加一些轮询/重试逻辑
首先看一下 没改之前的check_for_row_in_list_table
我们在没改的时候是休眠一秒,在这个时间内然后把参数row_text传入,先获取元素 id_list_table ,然后定位元素 tr
然后断言判断。但是我们不能确定的是他能够查到呢

    def check_for_row_in_list_table(self,row_text):
        table = self.browser.find_element_by_id("id_list_table")
        rows = table.find_elements_by_tag_name('tr')
        self.assertIn(
            row_text ,[row.text for row in rows]
        )

修改一下:

from selenium.common.exceptions import WebDriverException
MAX_WAIT = 10                      #设定准备等待的最长时间常量,10秒足够去应对潜在的问题和缓慢因素了
    def wait_for_row_in_list_table(self,row_text):
        start_time = time.time()
        while True:   #这个循环一直运行,直到遇到两个出口中的一个为止
            try:
            #断言跟上面比是没有变化的
                table = self.browser.find_element_by_id("id_list_table")      
                rows = table.find_elements_by_tag_name('tr')
                self.assertIn(
                    row_text ,[row.text for row in rows]
                )
                return  #如果断言正确就退出函数跳出循环了 
            except(AssertionError,WebDriverException) as e: #两种异常:AssertionError ,因为页面中虽然有表格,但是可能页面加载前        就存在,里面还是没有我们要找的行;WebDriverException 页面未加载或者selenium 未在页面找到表格元素时抛出。
                if time.time()-start_time > MAX_WAIT:
                    raise e   #第二出口  如果执行到此,说明代码有异常不断抛出,已经超过最大时间,因此这里再次抛出异常,向上冒泡,最终出现在调用跟踪中,指明测试失败原因 (  **Python中的raise 关键字**用于引发一个异常,基本上和C#和Java中的throw关键字相同格式: 主动抛出异常终止程序    raise 异常名称(‘异常描述’))
                time.sleep(0.5) # 如果捕获异常,那么就等待一小段时间,然后重新循环。

现在我们把time.sleep()去掉然后调用我们新写的方法
运行起来,跟原先一样的效果,不过运行时间快了几秒。哈哈
但是这并不能明确看出我们改动的是否合理,我们改动一下我们要查找的元素,故意写一个没有的,看一下抛出什么错误

        while True:
            try:
                table = self.browser.find_element_by_id("id_list")
                rows = table.find_elements_by_tag_name('tr')
                self.assertIn(
                    row_text ,[row.text for row in rows]
                )

结果:在这里插入图片描述
这个错误正是我们想要看到的结果:
改回原来,远行确认一下吧。

总结:
避免使用含糊的休眠:
一旦需要等待什么加载,我们第一反应是使用time.sleep ,但是这样做带来的问题是时间长度我们并不能确定:要么短容易假失败,要么长,拖慢测试。所以推荐使用重试循环,它可以轮询应用,今早的向前行走

不要依赖selenium 的隐式等待
selenium 的隐式等待在各个浏览器上的实现各不相同,隐式等待在selenium3 的Firefox 驱动上不太靠谱。
禅道:明了胜于晦涩 因此首选显示等待。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值