0


提升 Selenium 测试稳定性的秘诀:深入理解等待 API 的使用

目录

  1. 为什么需要等待
  2. Selenium 等待 API 简介
  3. 隐式等待
  4. 显式等待
  5. Fluent Wait
  6. 等待策略的选择
  7. 示例代码
  8. 总结

正文

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
  1. title_is
  2. title_contains
  3. presence_of_element_located
  4. visibility_of_element_located
  5. visibility_of
  6. presence_of_all_elements_located
  7. text_to_be_present_in_element
  8. text_to_be_present_in_element_value
  9. frame_to_be_available_and_switch_to_it
  10. invisibility_of_element_located
  11. element_to_be_clickable
  12. staleness_of
  13. element_to_be_selected
  14. element_located_to_be_selected
  15. 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,在实际项目中写出更加健壮的测试用例。


希望这个博客大纲和详细内容对你有所帮助!如果有任何进一步的问题或需要更多示例,请随时告诉我。


本文转载自: https://blog.csdn.net/abments/article/details/140049836
版权归原作者 abments 所有, 如有侵权,请联系我们删除。

“提升 Selenium 测试稳定性的秘诀:深入理解等待 API 的使用”的评论:

还没有评论