当前位置: 首页 > 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,在实际项目中写出更加健壮的测试用例。


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

相关文章:

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

目录 为什么需要等待Selenium 等待 API 简介隐式等待显式等待Fluent Wait等待策略的选择示例代码总结 正文 1. 为什么需要等待 在 Web 自动化测试中,等待是一个关键因素。网络应用通常是动态的,页面加载时间、元素的显示时间都可能不同步。直接操作这…...

Python-算法编程100例-滑动窗口(入门级)

题目1:最大连续1的个数(简单) 给定一个二进制数组 nums , 计算其中最大连续 1 的个数。 解答:前缀和双指针 # 给定一个二进制数组 nums , 计算其中最大连续 1 的个数。 from typing import Listclass So…...

ffmpeg使用mjpeg把yuvj420p编码为jpg图像

version #define LIBAVUTIL_VERSION_MAJOR 58 #define LIBAVUTIL_VERSION_MINOR 12 #define LIBAVUTIL_VERSION_MICRO 100 node 不使用AVOutputFormat code void CFfmpegOps::EncodeYUVJ420pToMJPEG(const char* infile, const char* width_str, const char* height_s…...

龙迅#LT6911GXC支持HDMI2.1转MIPI/4PORT LVDS应用功能,分辨率高达8K30HZ/4K120HZ压缩格式。

1. 描述 该LT6911GXC是一款高性能HD-DVI2.1转MIPI或LVDS芯片,适用于VR/显示应用。 HDCP RX作为HDCP中继器的上游,可以与其他芯片的HDCP TX配合实现中继器功能。 对于 HD-DVI2.1 输入,LT6911GXC可以配置为 3/4 通道。 对于MIPI输出&#xff0c…...

.NET 6.0 Web API项目中实现基于Token的身份验证

本文以一个完整的示例,展示如何在.NET 6.0 Web API项目中实现基于Token的身份验证。这个例子包括了如何创建和验证JWT Token,以及如何在控制器中使用这些Token。 步骤 1: 创建Web API项目 首先,用Visual Studio 2022创建一个基于.NET6.0的 …...

Java常用对象的快速初始化

在Java中,有多种方式来快速初始化各种常用对象,如字符串数组(String[]),集合列表(List),映射表(Map),以及集合(Set)。不同…...

逻辑回归模型模拟实现:从零开始

引言 逻辑回归是一种用于二分类问题的机器学习算法。尽管它的名字中有“回归”,但它实际上是用于分类的。在本文中,我们将通过模拟数据来演示逻辑回归模型的实现。 逻辑回归简介 逻辑回归通过使用逻辑函数(通常是Sigmoid函数)将…...

Docker基本使用和认识

目录 基本使用 镜像仓库 镜像操作 Docker 如何实现镜像 1) namespace 2) cgroup 3) LXC Docker常见的网络类型 bridge网络如何实现 基本使用 镜像仓库 镜像仓库登录 1)docker login 后面不指定IP地址,则默认登录到 docker hub 上 退出 2)docker logo…...

Halcon 文本文件操作,形态学

一文件的读写 *******************************************************向文本文件写入字符串内容*************************************************************read_image (Image, fabrik)threshold (Image, Region, 0, 120)area_center (Region, Area, Row, Column)open_…...

【鸿蒙】稍微理解一下Stage模型

鸿蒙的Stage模型是HarmonyOS多端统一的应用开发框架中的一个核心概念,用于描述应用的界面层次结构和组件之间的关系。下面将详细解析Stage模型的主要组成部分和特点: 模型组成: UIAbility组件:这是应用中负责绘制用户界面的组件&a…...

毕业答辩制作PPT【攻略】

毕业答辩制作PPT【攻略】 前言版权毕业答辩制作PPT【攻略】一、WPS AI 15天免费会员二、AI文档生成PPT三、修改完善PPT 最后 前言 2024-06-14 23:43:05 以下内容源自《【攻略】》 仅供学习交流使用 版权 禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作者是CSDN…...

深入解析npm install --save-dev:开发依赖管理的艺术

npm(Node Package Manager)是JavaScript编程语言的包管理器,用于管理项目中的依赖关系。在开发过程中,合理地管理依赖是保证项目可维护性和可扩展性的关键。npm install命令是npm中最常用的命令之一,而--save-dev参数则…...

福布斯 AI 50 榜单中唯一开源向量数据库:Weaviate

本篇文章,聊聊福布斯全球网站前俩月发布的 2023 AI 50 榜单中的唯一一个开源的向量数据库:Weaviate。 它在数据持久化和容错性上表现非常好、支持混合搜索、支持水平扩展,同时又保持了轻量化。官方主打做 AI 时代的原生数据库,减…...

信息学奥赛初赛天天练-38-CSP-J2021阅读程序-约数个数、约数和、埃氏筛法、欧拉筛法筛素数应用

PDF文档公众号回复关键字:20240628 2021 CSP-J 阅读程序3 1阅读程序(判断题1.5分 选择题3分 共计40分 ) 01 #include<stdio.h> 02 using namespace std; 03 04 #define n 100000 05 #define N n1 06 07 int m; 08 int a[N],b[N],c[N],d[N]; 09 int f[N],g[N]; 10 11 …...

第100+13步 ChatGPT学习:R实现决策树分类

基于R 4.2.2版本演示 一、写在前面 有不少大佬问做机器学习分类能不能用R语言&#xff0c;不想学Python咯。 答曰&#xff1a;可&#xff01;用GPT或者Kimi转一下就得了呗。 加上最近也没啥内容写了&#xff0c;就帮各位搬运一下吧。 二、R代码实现决策树分类 &#xff08;…...

Hi3861 OpenHarmony嵌入式应用入门--LiteOS MessageQueue

CMSIS 2.0接口中的消息&#xff08;Message&#xff09;功能主要涉及到实时操作系统&#xff08;RTOS&#xff09;中的线程间通信。在CMSIS 2.0标准中&#xff0c;消息通常是通过消息队列&#xff08;MessageQueue&#xff09;来进行处理的&#xff0c;以实现不同线程之间的信息…...

ffmpeg编码图象时报错Invalid buffer size, packet size * < expected frame_size *

使用ffmpeg将单个yuv文件编码转为jpg或其他图像格式时&#xff0c;报错&#xff1a; Truncating packet of size 11985408 to 3585 [rawvideo 0x1bd5390] Packet corrupt (stream 0, dts 1). image_3264_2448_0.yuv: corrupt input packet in stream 0 [rawvideo 0x1bd7c60…...

解决类重复的问题

1.针对AndroidX 类重复问题 解决办法&#xff1a; android.useAndroidXtrue android.enableJetifiertrue2.引用其他sdk出现类重复的问题解决办法&#xff1a;configurations {all { // You should exclude one of them not both of themexclude group: "com.enmoli"…...

使用 shell 脚本 统计app冷启动耗时

下面是一个 shell 脚本&#xff0c;它使用 参数将包名称作为参数--app&#xff0c;识别相应应用程序进程的 PID&#xff0c;使用 终止该进程adb shell kill&#xff0c;最后使用 重新启动该应用程序adb shell am start&#xff1a; #!/bin/bash# Check if package name is pro…...

使用容器部署redis_设置配置文件映射到本地_设置存储数据映射到本地_并开发java应用_连接redis---分布式云原生部署架构搭建011

可以看到java应用的部署过程,首先我们要准备一个java应用,并且我们,用docker,安装一个redis 首先我们去start.spring.io 去生成一个简单的web项目,然后用idea打开 选择以后下载 放在这里,然后我们去安装redis 在公共仓库中找到redis . 可以看到它里面介绍说把数据放到了/dat…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...