目录
- 为什么需要等待
- Selenium 等待 API 简介
- 隐式等待
- 显式等待
- Fluent Wait
- 等待策略的选择
- 示例代码
- 总结
正文
1. 为什么需要等待
在 Web 自动化测试中,等待是一个关键因素。网络应用通常是动态的,页面加载时间、元素的显示时间都可能不同步。直接操作这些元素可能会导致
NoSuchElementException
或者
ElementNotVisibleException
等错误。因此,等待机制可以帮助我们确保元素加载完成后再进行操作,从而提高测试的稳定性和可靠性。
2. Selenium 等待 API 简介
Selenium 提供了三种主要的等待机制:
- 隐式等待 (Implicit Wait)
- 显式等待 (Explicit Wait)
- Fluent Wait
3. 隐式等待
隐式等待是全局设置的一种等待方式,它会在查找元素时等待一定的时间,默认时间为 0 秒。
from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(10)# 设置隐式等待时间为 10 秒
driver.get("http://www.example.com")
element = driver.find_element_by_id("element_id")
当元素未立即可见时,WebDriver 将会每隔一段时间检查一次,直到达到指定的等待时间。如果在规定时间内找到了元素,将立即返回,否则抛出
NoSuchElementException
。
4. 显式等待
显式等待是针对特定元素的等待,它在等待条件满足前会定期检查元素的状态。
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("http://www.example.com")try:
element = WebDriverWait(driver,10).until(
EC.presence_of_element_located((By.ID,"element_id")))finally:
driver.quit()
WebDriverWait
结合
expected_conditions
模块可以灵活地等待元素的不同状态,如元素的可见性、元素的可点击性等。
expected_conditions
是 Selenium 提供的一组条件类,用于显式等待。这些条件可以用来判断特定元素或页面状态,以决定是否继续执行后续的操作。以下是一些常用的
expected_conditions
及其示例说明:
常用的
expected_conditions
title_is
title_contains
presence_of_element_located
visibility_of_element_located
visibility_of
presence_of_all_elements_located
text_to_be_present_in_element
text_to_be_present_in_element_value
frame_to_be_available_and_switch_to_it
invisibility_of_element_located
element_to_be_clickable
staleness_of
element_to_be_selected
element_located_to_be_selected
alert_is_present
示例说明
1.
title_is
等待页面标题等于指定值。
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
WebDriverWait(driver,10).until(EC.title_is("Expected Title"))
2.
title_contains
等待页面标题包含指定文本。
WebDriverWait(driver,10).until(EC.title_contains("Partial Title"))
3.
presence_of_element_located
等待元素出现在页面上。
from selenium.webdriver.common.by import By
element = WebDriverWait(driver,10).until(
EC.presence_of_element_located((By.ID,"element_id")))
4.
visibility_of_element_located
等待元素可见。
element = WebDriverWait(driver,10).until(
EC.visibility_of_element_located((By.ID,"element_id")))
5.
visibility_of
等待一个已知元素对象可见。
element = driver.find_element_by_id("element_id")
WebDriverWait(driver,10).until(EC.visibility_of(element))
6.
presence_of_all_elements_located
等待一组元素全部出现在页面上。
elements = WebDriverWait(driver,10).until(
EC.presence_of_all_elements_located((By.CLASS_NAME,"class_name")))
7.
text_to_be_present_in_element
等待元素中包含指定文本。
WebDriverWait(driver,10).until(
EC.text_to_be_present_in_element((By.ID,"element_id"),"Expected Text"))
8.
text_to_be_present_in_element_value
等待元素的值包含指定文本。
WebDriverWait(driver,10).until(
EC.text_to_be_present_in_element_value((By.ID,"input_id"),"Expected Value"))
9.
frame_to_be_available_and_switch_to_it
等待 iframe 可用并切换到该 frame。
WebDriverWait(driver,10).until(
EC.frame_to_be_available_and_switch_to_it((By.NAME,"frame_name")))
10.
invisibility_of_element_located
等待元素不可见。
WebDriverWait(driver,10).until(
EC.invisibility_of_element_located((By.ID,"element_id")))
11.
element_to_be_clickable
等待元素可点击。
element = WebDriverWait(driver,10).until(
EC.element_to_be_clickable((By.ID,"clickable_element_id")))
element.click()
12.
staleness_of
等待元素不再附加在 DOM 树上。
element = driver.find_element_by_id("stale_element_id")
WebDriverWait(driver,10).until(EC.staleness_of(element))
13.
element_to_be_selected
等待元素被选中。
element = driver.find_element_by_id("select_element_id")
WebDriverWait(driver,10).until(EC.element_to_be_selected(element))
14.
element_located_to_be_selected
等待特定定位器的元素被选中。
WebDriverWait(driver,10).until(
EC.element_located_to_be_selected((By.ID,"select_element_id")))
15.
alert_is_present
等待警告框出现。
WebDriverWait(driver,10).until(EC.alert_is_present())
alert = driver.switch_to.alert
alert.accept()
通过这些
expected_conditions
,你可以更加灵活地控制 Selenium 测试的等待逻辑,确保测试脚本在正确的时间点进行操作。
5. Fluent Wait
Fluent Wait 是显式等待的一种扩展,它允许我们定义等待的最大时间、轮询的频率以及在等待期间遇到的异常处理。
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
driver = webdriver.Chrome()
driver.get("http://www.example.com")
wait = WebDriverWait(driver,10, poll_frequency=1, ignored_exceptions=[TimeoutException])
element = wait.until(EC.presence_of_element_located((By.ID,"element_id")))
Fluent Wait 通过指定轮询频率,可以更精确地控制等待行为。
6. 等待策略的选择
选择合适的等待策略取决于测试的具体需求:
- 隐式等待 适用于大部分情况下的全局设置,但可能导致调试困难,因为它在所有元素查找时都生效。
- 显式等待 提供了更精确的控制,适用于需要等待特定条件的场景。
- Fluent Wait 是显式等待的高级版本,适用于需要自定义轮询频率和异常处理的复杂场景。
7. 示例代码
综合使用不同等待机制的示例代码:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("http://www.example.com")# 设置隐式等待
driver.implicitly_wait(10)try:# 使用显式等待
element = WebDriverWait(driver,10).until(
EC.presence_of_element_located((By.ID,"element_id")))# 使用 Fluent Wait
wait = WebDriverWait(driver,10, poll_frequency=1, ignored_exceptions=[TimeoutException])
element = wait.until(EC.element_to_be_clickable((By.ID,"clickable_element_id")))
element.click()finally:
driver.quit()
8. 总结
等待机制在 Selenium 测试中起到了至关重要的作用。通过合理选择和使用隐式等待、显式等待和 Fluent Wait,可以大大提高自动化测试的稳定性和可靠性。希望这篇博客能帮助你更好地理解和应用 Selenium 的等待 API,在实际项目中写出更加健壮的测试用例。
希望这个博客大纲和详细内容对你有所帮助!如果有任何进一步的问题或需要更多示例,请随时告诉我。
版权归原作者 abments 所有, 如有侵权,请联系我们删除。