当前位置: 首页 > news >正文

提升 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 webdriverdriver = 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 ECdriver = 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 ECWebDriverWait(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 Byelement = 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 TimeoutExceptiondriver = 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 ECdriver = 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 Waitwait = 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,在实际项目中写出更加健壮的测试用例。


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

http://www.lryc.cn/news/386126.html

相关文章:

  • Python-算法编程100例-滑动窗口(入门级)
  • ffmpeg使用mjpeg把yuvj420p编码为jpg图像
  • 龙迅#LT6911GXC支持HDMI2.1转MIPI/4PORT LVDS应用功能,分辨率高达8K30HZ/4K120HZ压缩格式。
  • .NET 6.0 Web API项目中实现基于Token的身份验证
  • Java常用对象的快速初始化
  • 逻辑回归模型模拟实现:从零开始
  • Docker基本使用和认识
  • Halcon 文本文件操作,形态学
  • 【鸿蒙】稍微理解一下Stage模型
  • 毕业答辩制作PPT【攻略】
  • 深入解析npm install --save-dev:开发依赖管理的艺术
  • 福布斯 AI 50 榜单中唯一开源向量数据库:Weaviate
  • 信息学奥赛初赛天天练-38-CSP-J2021阅读程序-约数个数、约数和、埃氏筛法、欧拉筛法筛素数应用
  • 第100+13步 ChatGPT学习:R实现决策树分类
  • Hi3861 OpenHarmony嵌入式应用入门--LiteOS MessageQueue
  • ffmpeg编码图象时报错Invalid buffer size, packet size * < expected frame_size *
  • 解决类重复的问题
  • 使用 shell 脚本 统计app冷启动耗时
  • 使用容器部署redis_设置配置文件映射到本地_设置存储数据映射到本地_并开发java应用_连接redis---分布式云原生部署架构搭建011
  • 第五节:如何使用其他注解方式从IOC中获取bean(自学Spring boot 3.x的第一天)
  • Paragon NTFS与Tuxera NTFS有何区别 Mac NTFS 磁盘读写工具选哪个好
  • EtherCAT主站IGH-- 2 -- IGH之coe_emerg_ring.h/c文件解析
  • psensor 的手势功能
  • 使用 nvm 管理 Node 版本及 pnpm 安装
  • uni-appx使用form表单页面初始化报错
  • TiDB-从0到1-数据导出导入
  • 动手学深度学习(Pytorch版)代码实践 -卷积神经网络-16自定义层
  • 树莓派4设置
  • 44.商城系统(二十五):k8s基本操作,ingress域名访问,kubeSphere可视化安装
  • MySQL高级查询