提升 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…...
ARM ETE Trace ID寄存器详解与应用
1. ARM ETE Trace ID寄存器概述在ARM架构的嵌入式调试系统中,Trace ID寄存器(TRCIDR)是嵌入式跟踪宏单元(ETE)的核心组件。这些寄存器提供了非侵入式的实时程序流分析能力,对于芯片验证、性能优化和系统调试具有不可替代的价值。ETE的Trace ID寄存器从TR…...
基于Rust与智能体范式构建生产级AI工作流:从Dust平台实践到避坑指南
1. 从零到一:理解Dust平台的核心价值与设计哲学如果你和我一样,每天都在和代码、文档、数据打交道,那你肯定也经历过这样的时刻:为了一个简单的数据查询,需要在不同工具间反复切换;为了写一份周报ÿ…...
Cap框架解析:模块化开发者工具箱的设计哲学与核心实践
1. 项目概述:一个面向开发者的现代化软件工具箱最近在GitHub上看到一个挺有意思的项目,叫“CapSoftware/Cap”。乍一看这个名字,可能会联想到“Cap”这个英文单词的多种含义——帽子、上限、或者电容的单位。但在软件开发的语境里,…...
2026盘古石取证初赛(APK取证)
APK取证1.分析方俊朗phone.E01检材,筛选优质客户应用将用户查询记录存储在一个加密的本地数据库中。请问该加密数据库的文件名是什么?[答案格式:12_abc.db]题目说了这边是筛选优质客户,其实和手机取证最后一题一样的,先…...
深入理解STM32的FSMC:如何像操作SRAM一样轻松点亮你的TFTLCD屏幕
深入理解STM32的FSMC:如何像操作SRAM一样轻松点亮你的TFTLCD屏幕 在嵌入式开发领域,TFTLCD屏幕的驱动一直是让开发者又爱又恨的难题。传统的GPIO模拟时序方式虽然简单直接,但在高分辨率屏幕和复杂应用场景下往往力不从心。这时,S…...
告别启动盘识别难题:手把手教你搞定CentOS 7在SR650上的UEFI启动与自定义分区(含/dev/sdX查找技巧)
告别启动盘识别难题:手把手教你搞定CentOS 7在SR650上的UEFI启动与自定义分区(含/dev/sdX查找技巧) 在服务器运维领域,系统安装看似基础却暗藏玄机。特别是当面对企业级硬件如Lenovo SR650时,UEFI启动模式与传统BIOS的…...
XUnity自动翻译器:打破语言壁垒的终极Unity游戏汉化解决方案
XUnity自动翻译器:打破语言壁垒的终极Unity游戏汉化解决方案 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 你是否曾经因为语言障碍而错过精彩的游戏剧情?是否在面对日文RPG或英文…...
FanControl中文设置终极指南:3个简单步骤让Windows风扇控制说中文
FanControl中文设置终极指南:3个简单步骤让Windows风扇控制说中文 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_…...
开源密钥管理器VSV:一个加密文件搞定多环境密钥管理
1. 项目概述:一个面向开发者的加密密钥管理器最近在折腾一个内部项目,需要管理不同环境(开发、测试、生产)的数据库密码、API密钥这些敏感信息。一开始图省事,直接写在了.env文件里,结果在代码评审时被同事…...
LVGL图片资源全解析:从C数组到图标字体的高效集成方案
1. LVGL图片资源方案概述 在嵌入式GUI开发中,图片资源的管理直接影响产品性能和开发效率。LVGL作为轻量级图形库,提供了三种主流的图片集成方案:内部C数组、外部文件系统图片和图标字体。每种方案都有其独特的适用场景和实现方式,…...
