在进行自动化测试时,对元素的操作通常都是比较迅速的,而有时会由于页面元素加载需要时间,或页面遮罩未及时关闭导致操作元素失败,这时,就需要用到等待,所谓等待,就是等待元素满足指定条件再执行后续操作,这在测试中对保证成功执行测试通常是非常有用的,常用的等待方式有3种,分别为
隐式等待
显示等待
强制等待
下面将对3种等待方式逐一说明
1、隐式等待
设置隐式等待后,webdriver在查找任何元素时都会在一定时间内轮询DOM,在某些元素需要时间加载显示时这通常很有用,但由于使用其会与后续介绍的显式等待冲突导致一些不可控的结果,所以在实际测试中个人不建议使用此等待方式,隐式等待语法如下
from selenium import webdriver
driver = webdriver.Edge()
driver.implicitly_wait(10) # 隐式等待,最多可在10S内轮询查找元素
2、显式等待
显式等待在实际测试中用得非常广泛,正确的使用显式等待,可以使得测试更加流畅,效率更高,显式等待使用语法如下:
from selenium import webdriver
driver = webdriver.Edge()
WebDriverWait(driver, timeout=5, poll_frequency=1, ignored_exceptions='ElementNotVisibleException').until(
some_condition)
其中timeout表示等待超时时长,poll_frequency表示等待时轮询的频次,ignored_exceptions表示等待过程中忽略的异常,默认情况下仅包含NoSuchElementException
可定义的超时时长、轮询频次、需要忽略的异常让显式等待显得更加灵活,而until()函数的应用更使得显式等待可以满足测试过程中绝大多数的应用场景,这就是some_condition参数的应用
实际测试过程中,有时我们需要等待元素加载可见,有时我们需要等待元素可点击等,selenium的support包中的expected_conditions.py为我们提供了很好的支持,以满足不同的测试场景
示例如下:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
driver = webdriver.Edge()
driver.get("https://www.baidu.com/")
element = driver.find_element(By.ID, 'kw')
WebDriverWait(driver, 5).until(EC.element_to_be_clickable(element)) # 等待元素可点击
其中等待元素可点击的代码表示,5秒内等待指定元素知道元素变为可点击状态,如果5秒内未变为可点击状态,则抛出有异常,5秒内任何时间变为可点击状态,则继续执行后续代码(不用等满5S)
除了等待元素可点击外,expected_conditions还提供了很多常见的场景支持,主要的有:
检查给定属性是否包含在指定元素中:
element_attribute_to_include(locator, attribute_)
定位元素并检查该元素的选中状态是否满足期望,is_selected为Boolean类型
element_located_selection_state_to_be(locator, is_selected)
给定的元素是被选中状态
element_located_to_be_selected(locator)
element_to_be_selected(element)
检查元素是否可点击(可见且启用的)
element_to_be_clickable(locator)
检查给定元素定位所在frame是否可切换,若可以将切换到其所在的frame
frame_to_be_available_and_switch_to_it(locator)
检查元素在DOM中不可见或不存在
invisibility_of_element(element)
invisibility_of_element_located(locator)
检查页面存在某元素,元素不一定可见
presence_of_element_located(locator)
等待元素不在附加在DOM中(消失、不存在)
staleness_of(element)
检查指定元素中是否存在指定文本
text_to_be_present_in_element(locator, text_)
检查页面title包含指定字符串
title_contains(title)
检查页面title匹配指定字符串
title_is(title)
检查url与指定url不同
url_changes(url)
检查指定元素可见,可见表示元素不仅显式,且宽度高度都大于0
visibility_of(element)
visibility_of_element_located(locator)
更多支持请参考官方文档说明或阅读源码查看,官方文档地址:
https://www.selenium.dev/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.expected_conditions.html?highlight=expected
3、强制等待
强制等待是使用python的time类实现的,示例代码如下
from selenium import webdriver
import time
driver = webdriver.Edge()
driver.get("https://www.baidu.com/")
time.sleep(5) # 强制等待5秒
强制等待表示无论如何必须等待满指定的时间,如果在测试中大量使用将严重影响测试效率,且由于强制等待后无法判断条件是否满足,所以可能由于指定时间内条件未满足而导致测试失败,所以如非实在必要,不建议使用强制等待