Selenium常用的元素等待方法

2019年1月17日 5.9k 次阅读 1 条评论 4 人点赞

写在前面

日常的UI自动化测试,单步调试的时候元素可以定位到,并且可以正常操作,但是在跑测试案例流程的时候反而报错。这时就需要考虑是否界面的切换,或者功能的跳转缓慢导致元素未加载完成就执行了操作,所以我们需要加上元素等待。WebDriver提供了几种类型的等待:强制等待、显式等待和隐式等待。

强制等待

设置等待最简单的方法就是强制等待,其实就是time.sleep()方法,不管它什么情况,让程序暂停运行一定时间,时间过后继续运行;缺点是不智能,如果设置的时间太短,元素还没有加载出来一样会报错;设置的时间太长,则会浪费时间.这个方式一般比较少用。

#testclass.py
#www.testclass.cn
#Altumn

from selenium import webdriver
import time

driver = webdriver.Chrome()  
driver.maximize_window()
driver.implicitly_wait(30) # 隐性等待,最长等30秒; 
driver.get('https://www.testclass.cn')
time.sleep(3)#强制等待3秒;

driver.quit()  

隐式等待

WebDriver提供了implicitly_wait()方法来实现隐式等待。隐式等待相当于设置全局等待,在定位元素时,对所有元素设置的超时时间。implicitly_wait()默认参数的单位为秒,默认设置为0。本例中设置等待时长为10秒。

注:默认设置超时时间为0,设置后这个隐式等待会在WebDriver对象实例的整个生命周期起作用。

#Baidu.py
#www.testclass.cn
#Altumn

from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from time import ctime

driver = webdriver.Chrome()

# 设置隐式等待为10秒;
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")

#处理异常机制;此案例正常不会超时抛出异常;
try:
    print(ctime())
    driver.find_element_by_id("kw").send_keys('www.testclass.cn')
except NoSuchElementException as e:
    print(e)
finally:
    print(ctime())
    driver.quit()

在上面的案例中implicitly_wait()设置等待时长为10秒。这个10秒的设置并不针对页面上的某一个元素进行等待,也不是一个固定的等待时间。如果设置了隐式等待,当元素定位时,如果元素可以正常定位,则继续执行;如果元素定位失败,将以轮询的方式不断地判断元素是否被定位到。直到超出设置时长(10秒)还没有定位到元素,则抛出异常。 抛出异常的案例:

#Baidu.py
#www.testclass.cn
#Altumn

from time import ctime
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException

driver = webdriver.Chrome()

# 设置隐式等待为10秒;
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")

#处理异常机制;超出设置时长(10秒)还没有定位到元素,则抛出异常;
try:
    print(ctime())
    driver.find_element_by_id("kw_test").send_keys('www.testclass.cn')
except NoSuchElementException as e:
    print(e)
finally:
    print(ctime())
    driver.quit()

执行结果:

显式等待

接下来介绍一种更智能的等待方式:显示等待。显示等待比隐式等待更节省测试时间,个人更推荐使用显示等待的方式来判断页面元素是否出现。程序会每隔一段时间(默认为0.5秒,可自定义)执行一下判断条件,等待某个条件成立时继续执行,否则在达到最大时长抛出超时异常(TimeoutException);WebDriverWait()类是由WebDirver 提供的等待方法。在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超过设置时间检测不到则抛出异常。

WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
driver :浏览器驱动。
timeout :最长超时时间,默认以秒为单位。
poll_frequency :检测的间隔(步长)时间,默认为0.5S。
ignored_exceptions :超时后的异常信息,默认情况下抛NoSuchElementException异常。

WebDriverWait()一般由until()until_not()方法配合使用,下面是until()until_not()方法的说明。

  • until(method, message=‘’)
  • method: 在等待期间,每隔一段时间调用这个传入的方法,直到返回值为True;message: 如果超时,抛出TimeoutException,将message传入异常。

  • until_not(method, message=‘’)
  • method: 在等待期间,每隔一段时间调用这个传入的方法,直到返回值为False;message: 如果超时,抛出TimeoutException,将message传入异常。

    为了更直观的演示处理效果,制作了一个html。Confirm提示框传送门:Confirm[请点点我]

    #Baidu.py
    #www.testclass.cn
    #Altumn
    
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    #导入模块,将expected_conditions 重命名为EC ;
    from selenium.webdriver.support import expected_conditions as EC
    
    driver = webdriver.Chrome()
    driver.maximize_window()
    driver.get("https://www.testclass.cn/test_html/Confirm.html")
    
    
    #等待标题是'confirm'的网页出现;
    element = WebDriverWait(driver, 5,0.5).until(EC.title_is(u'confirm'))
    #网页出现后打印一下提示;
    print(u'网页标题是:“confirm”')
    #等待元素属性NAME="button"点击按钮出现;
    element = WebDriverWait(driver, 5,0.5).until(EC.presence_of_element_located((By.NAME, "button")))
    element.click()
    
    #等待Alert框出现;
    alert=WebDriverWait(driver,5,0.5).until(EC.alert_is_present())
    #定位到Alert;
    alert = driver.switch_to.alert
    #获取Alert的Text值;
    print(alert.text)
    #确定Alert;
    alert.accept()
    
    #设置等待Alert消失;
    WebDriverWait(driver,5,0.5).until_not(EC.alert_is_present())
    print(u'弹出框Alert已经被关闭啦~')
    

    执行结果:

    风里云里,我在这里等你!

    文章评论(1)

  • 11

    自动化测试学习交流群:670250199

    2019年3月28日