提升 Selenium 测试稳定性的秘诀:深入理解等待 API 的使用
目录
- 为什么需要等待
- Selenium 等待 API 简介
- 隐式等待
- 显式等待
- Fluent Wait
- 等待策略的选择
- 示例代码
- 总结
正文
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
title_istitle_containspresence_of_element_locatedvisibility_of_element_locatedvisibility_ofpresence_of_all_elements_locatedtext_to_be_present_in_elementtext_to_be_present_in_element_valueframe_to_be_available_and_switch_to_itinvisibility_of_element_locatedelement_to_be_clickablestaleness_ofelement_to_be_selectedelement_located_to_be_selectedalert_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输出,…...
.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语言,不想学Python咯。 答曰:可!用GPT或者Kimi转一下就得了呗。 加上最近也没啥内容写了,就帮各位搬运一下吧。 二、R代码实现决策树分类 (…...
Hi3861 OpenHarmony嵌入式应用入门--LiteOS MessageQueue
CMSIS 2.0接口中的消息(Message)功能主要涉及到实时操作系统(RTOS)中的线程间通信。在CMSIS 2.0标准中,消息通常是通过消息队列(MessageQueue)来进行处理的,以实现不同线程之间的信息…...
ffmpeg编码图象时报错Invalid buffer size, packet size * < expected frame_size *
使用ffmpeg将单个yuv文件编码转为jpg或其他图像格式时,报错: 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 类重复问题 解决办法: android.useAndroidXtrue android.enableJetifiertrue2.引用其他sdk出现类重复的问题解决办法:configurations {all { // You should exclude one of them not both of themexclude group: "com.enmoli"…...
使用 shell 脚本 统计app冷启动耗时
下面是一个 shell 脚本,它使用 参数将包名称作为参数--app,识别相应应用程序进程的 PID,使用 终止该进程adb shell kill,最后使用 重新启动该应用程序adb shell am start: #!/bin/bash# Check if package name is pro…...
使用容器部署redis_设置配置文件映射到本地_设置存储数据映射到本地_并开发java应用_连接redis---分布式云原生部署架构搭建011
可以看到java应用的部署过程,首先我们要准备一个java应用,并且我们,用docker,安装一个redis 首先我们去start.spring.io 去生成一个简单的web项目,然后用idea打开 选择以后下载 放在这里,然后我们去安装redis 在公共仓库中找到redis . 可以看到它里面介绍说把数据放到了/dat…...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 ` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
