吊打 Web 自动化测试!一篇吃透 Selenium 元素定位 + 核心函数,新手直接上手

吊打 Web 自动化测试!一篇吃透 Selenium 元素定位 + 核心函数,新手直接上手

目录

一、前言

通过概念篇,你一定理解了web自动化示例怎么就能按照你的代码执行自动化,但是又可能又会带有新的好奇,一个web网页界面这么多元素,它是怎么找到的,还有好几个如findElement() 等方法中,怎么有些出现了奇怪的字符串,它又是用来干什么的,它们作业又是什么?
别慌,这些东西只是涉及到元素的定位和⾃动化测试常⽤函数内容,今天这篇文章就来让你来更深刻的掌握自动化测试,保证你看完后,直接可以上手项目测试

二、元素的定位

web⾃动化测试的操作核⼼是能够找到⻚⾯对应的元素,然后才能对元素进⾏具体的操作。
常⻅的元素定位⽅式⾮常多,如id,classname,tagname,xpath,cssSelector常⽤的主要由cssSelectorxpath

1. xpath

XML路径语⾔,不仅可以在XML⽂件中查找信息,还可以在HTML中选取节点。
xpath使⽤路径表达式来选择xml⽂档中的节点

1.2. 找到“xpath 路径”

通过边用边学的方法来学如何正确使用xpath
目的: 找到输入框

在这里插入图片描述


By.xpath("xxx"):用 “xpath 路径” 定位输入框
找到 “xpath 路径”
1.打开浏览器并进入百度一下首页
2.按键盘F12,打开‌开发者工具‌
3.点击左上角的 ’Select an element in the page to inspect it’ ,将鼠标移动到搜索框上后点击鼠标

在这里插入图片描述

点击后的蓝色框就是要定位的元素位置

在这里插入图片描述


4.将鼠标移动到蓝色框后点击鼠标右键点击Copy后在点击Copy XPath
此刻复制的内容,就是 “xpath 路径”

在这里插入图片描述

1.3 xpath语法

  1. //*:获取HTML⻚⾯所有的节点

2. //[指定节点]:获取HTML⻚⾯指定的节点

//ul :获取HTML⻚⾯所有的ul节点
  1. / :获取⼀个节点中的直接⼦节点
//*[@id=“chat-input-main”]/div[4]/div[1]/div[1]
  1. [@...] :实现节点属性的匹配
//*[@id=‘kw’]匹配HTML⻚⾯中id属性为kw的节点

注意:元素的定位⽅法必须唯⼀

2. cssSelector

选择器的功能:选中⻚⾯中指定的标签元素
选择器的种类分为基础选择器和复合选择器,常⻅的元素定位⽅式可以通过id选择器和⼦类选择器来进⾏定位。

2.1 使用选择器定位元素

cssSelector的元素定位方法和找到“xpath 路径”一样,只不过最后点击的是Copy selector

在这里插入图片描述


目的: 定位百度搜索框
By.cssSelector("xxx"):用选择器定位输入框

在这里插入图片描述

三、⾃动化测试常⽤函数

3.1 操作测试对象

获取到了⻚⾯的元素之后,接下来就是要对元素进⾏操作了。常⻅的操作有点击、提交、输⼊、清除、获取⽂本

click()

作用: 为点击/提交对象
代码演示
目的: 找到百度⼀下按钮并点击

driver.findElement(By.xpath("//*[@id=\"chat-submit-button\"]")).click();

通过xpath路径定位到元素后,通过click()点击,相当于,找到百度⼀下按钮并点击

特殊元素

页面上的绝大数的元素都可以点击,只有部分页面隐藏的,不可见的标签元素无法点击

对不可交互的元素执行,会报错

在这里插入图片描述

sendKeys(“”)

作用: 模拟按键输⼊
代码演示
目的: 找到搜索框并输入“胡歌”

driver.findElement(By.xpath("//*[@id=\"chat-textarea\"]")).sendKeys("胡歌");

连续的sendKeys具有追加效果

//追加效果 driver.findElement(By.xpath("//*[@id=\"chat-textarea\"]")).sendKeys("胡歌"); driver.findElement(By.xpath("//*[@id=\"chat-textarea\"]")).sendKeys("邓超");
在这里插入图片描述

clear()

作用: 清除⽂本内容
输⼊⽂本后⼜想换⼀个新的关键词,这⾥就需要⽤到clear()
代码演示
目的: 找到搜索框并输入“胡歌”后清理输入框中的“胡歌”

driver.findElement(By.xpath("//*[@id=\"chat-textarea\"]")).sendKeys("胡歌"); driver.findElement(By.xpath("//*[@id=\"chat-textarea\"]")).clear();

getText()

作用: 获取⽂本信息
通过getText我们可以判断获取到的元素是否符合预期
目的: 找到搜索框并输入“胡歌”后获取对应元素的文本内容

 driver.findElement(By.xpath("//*[@id=\"chat-textarea\"]")).sendKeys("胡歌");String text =driver.findElement(By.xpath("//*[@id=\"chat-textarea\"]")).getText();System.out.println("获取到的文本为:"+text);

注意:getText()只可以获取信息⽂本,不可以获取属性值,获取属性值需要使⽤⽅法getAttribute("属性名称")

在这里插入图片描述

getTitle()

作用: 获取当前⻚⾯标题

WebDriver driver =newChromeDriver(options); driver.get("https://www.baidu.com"); driver.getTitle();// 获取当前页面标题:“百度一下,你就知道”

getCurrentUrl()

作用: 获取当前⻚⾯URL

WebDriver driver =newChromeDriver(options); driver.get("https://www.baidu.com"); driver.getCurrentUrl();//获取当前⻚⾯URL:https://www.baidu.com/
扩展窗口问题

当我们执行进入百度页面后点击图片的自动化操作效果,用 getCurrentUrl() 获取当前⻚⾯URL,按照我们执行的思路,想必获取的肯定是图片页面的URL吧

//进入百度页面后点击图片页面 driver.get("https://www.baidu.com");String titleBefore=driver.getTitle();String urlBefore=driver.getCurrentUrl(); driver.findElement(By.xpath("//*[@id=\"s-top-left\"]/a[6]")).click();String titleAfter=driver.getTitle(); driver.getCurrentUrl();String urlAfter=driver.getCurrentUrl();System.out.println("跳转之前的标题:"+titleBefore);System.out.println(urlBefore);System.out.println("跳转之后的标题:"+titleAfter);System.out.println(urlAfter);
在这里插入图片描述


自动化执行成功,说明已经按照代码的执行,进入百度页面后点击图片页面进入图片页面,但是通过打印的日志得知并没有获取跳转后图片页面的url和标题,这就奇怪了明明代码是执行成功的.

页面句柄

其实核心原因是新标签页打开后, driver 实例仍停留在原标签页,所以获取的还是原页面的信息,每个标签页都会有自己页面的句柄,我们可以通过getWindowHandle()打印标签页句来验证driver 实例是否仍停留在原标签页

getWindowHandle()获取当前句柄
getWindowHandles()获取所有页面的句柄,用set存储所有句柄
//进入百度页面后点击图片页面 driver.get("https://www.baidu.com");System.out.println("当前页面句柄:"+driver.getWindowHandle());String titleBefore=driver.getTitle();String urlBrfore=driver.getCurrentUrl(); driver.findElement(By.xpath("//*[@id=\"s-top-left\"]/a[6]")).click();System.out.println("当前页面句柄:"+driver.getWindowHandle());String titleAfter=driver.getTitle(); driver.getCurrentUrl();String urlAfter=driver.getCurrentUrl();System.out.println("跳转之前的标题:"+titleBefore);System.out.println(urlBrfore);System.out.println("跳转之后的标题:"+titleAfter);System.out.println(urlAfter);
在这里插入图片描述


通过验证 driver 实例仍停留在原标签页,所以如果要获得跳转页面的url之类的,直接用 getCurrentUrl 是行不通的,这时我们就要使用页面切换,使得driver 实例停留在跳转页面标签页

页面切换

driver.switchTo().window() 表示将driver实例停留在输入的句柄中,也就是页面切换

切换页面示例演示

//进入百度页面后点击图片页面 driver.get("https://www.baidu.com");String curWindow=driver.getWindowHandle();System.out.println("当前页面句柄:"+curWindow);String titleBefore=driver.getTitle();String urlBrfore=driver.getCurrentUrl();System.out.println("跳转之前的标题:"+titleBefore);System.out.println(urlBrfore); driver.findElement(By.xpath("//*[@id=\"s-top-left\"]/a[6]")).click();System.out.println("打印当前页面所有句柄:");Set<String> allWindow = driver.getWindowHandles();for(String window:allWindow){System.out.println(window);}//切换页面for(String window : allWindow){if(!window.equals(curWindow)){ driver.switchTo().window(window);}}String titleAfter=driver.getTitle();String urlAfter=driver.getCurrentUrl();System.out.println("跳转之后的标题:"+titleAfter);System.out.println(urlAfter);//5、关闭浏览器 driver.quit();
在这里插入图片描述

根据运行结果,自动化按照我们想执行的思路,成功获取跳转后的url

3.2 窗⼝

窗⼝设置⼤⼩

//窗⼝最⼤化 driver.manage().window().maximize();//窗⼝最⼩化  driver.manage().window().minimize();//全屏窗⼝ driver.manage().window().fullscreen();//⼿动设置窗⼝⼤⼩ driver.manage().window().setSize(newDimension(1024,768));

屏幕截图

我们的⾃动化脚本⼀般部署在机器上⾃动的去运⾏,如果出现了报错,我们是不知道的,可以通过抓拍来记录当时的错误场景
屏幕截图⽅法需要额外导⼊包:

<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version></dependency>
//捕获截图并生成临时文件File file =((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);//将临时截图文件复制到指定路径FileUtils.copyFile(file,newFile(filename));

代码演示:捕获百度首页截图

//驱动程序管理的自动化WebDriverManager.chromedriver().setup();ChromeOptions options =newChromeOptions();//允许访问所有链接 options.addArguments("--remote-allow-origins=*");//1、打开浏览器WebDriver driver =newChromeDriver(options); driver.get("https://www.baidu.com");File file=((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);FileUtils.copyFile(file,newFile("test.png"));//5、关闭浏览器 driver.quit();

运行结果:

在这里插入图片描述
避免截图覆盖问题

直接将临时截图文件复制会因为图片名字一样而造成截图覆盖问题,避免生成屏幕截图的图片文件因为重名而被覆盖,要求每次生成的屏幕截图图片文件名称是唯一的,这时就可以用时间戳来命名文件

2025-12-26 2025-12-27
хxхxхххх.png хxXXXXxX.png
xxxxxxxX.png xxXxxXXx.png
年月日时分秒亳秒
2025-12-26-18484950.png 2025-12-27-18184955.png
2025-12-26-18484955.png
WebDriverManager.chromedriver().setup();ChromeOptions options =newChromeOptions(); options.addArguments("--remote-allow-origins=*");WebDriver driver =newChromeDriver(options);//用时间搓来命名文件名SimpleDateFormat sim1 =newSimpleDateFormat("yyyy-MM-dd");SimpleDateFormat sim2 =newSimpleDateFormat("HH-mm-ss-SS");String dirTime = sim1.format(System.currentTimeMillis());String fileTime = sim2.format(System.currentTimeMillis());// 图片文件名: ./src/test/images/2025-12-26/18-56-57-50.pngString filename ="./src/test/images/"+ dirTime +"/"+ fileTime +".png";File srcfile =((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);FileUtils.copyFile(srcfile,newFile(filename)); driver.quit();

运行结果:

在这里插入图片描述

关闭窗⼝

driver.close()为关闭当前被 driver 聚焦的标签页 / 窗口,注意不是关闭整个浏览器,如果只有一个窗口的情况下才会关闭整个浏览器

3.3 等待

通常代码执⾏的速度⽐⻚⾯渲染的速度要快,如果避免因为渲染过慢出现的⾃动化误报的问题呢?可以使⽤selenium中提供的三种等待⽅法:

1. Thread.sleep()

Thread.sleep() 这个大家应该很熟悉了就是将阻塞当前线程,线程阻塞了,自然可以等待的⻚⾯渲染
优点:使⽤简单,调试的时候⽐较有效
缺点:影响运⾏效率,如果有上千个页面,那浪费⼤量的时间

2. 隐式等待

隐式等待是⼀种智能等待,他可以规定在查找元素时,在指定时间内不断查找元素。如果找到则代码继续执⾏,直到超时没找到元素才会报错
优点:智能等待,作⽤于全局
使用implicitlyWait(),参数为Duration类中提供的毫秒、秒、分钟等⽅法

在这里插入图片描述

示例:

//隐式等待2000毫秒  driver.manage().timeouts().implicitlyWait(Duration.ofMillis(2000));//隐式等待2秒  driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
隐式等待作⽤域是整个脚本的所有元素。即只要driver对象没有被释放掉(driver.quit()),隐式等待就⼀直⽣效

3. 显⽰等待

显式等待是指针对特定的元素或条件,设置一个最长等待时间,在这个时间范围内,程序会周期性地检查条件是否满足。一旦条件满足,就立即执行后续操作;如果超过最长等待时间条件仍不满足,则抛出超时异常

在这里插入图片描述

它和隐式等待(Implicit Wait) 最大的区别是:显式等待是针对性的、更灵活的,只作用于指定的元素 / 条件,而隐式等待是全局的、对所有元素生效

优点:显⽰等待是智能等待,可以⾃定义显⽰等待的条件,操作灵活
缺点:写法复杂,作用于单个 / 特定元素的单次操作,只针对你指定的某个元素、某个条件生效,是 “按需触发” 的局部等待

显⽰等待的格式:

newWebDriverWait(driver,Duration.ofSeconds(5)).until()

Duration.ofSeconds()和隐式等待一样:参数为Duration类中提供的毫秒、秒、分钟等⽅法

在这里插入图片描述

until 参数:涉及到selenium.support.ui.ExpectedConditions包下的ExpectedConditions类

ExpectedConditions预定义⽅法的⼀些⽰例

  • elementToBeClickable(By locator): ⽤于检查元素的期望是可⻅的并已启⽤,以便您可以单击它
  • textToBe(Bylocator,String str): 检查元素
  • presenceOfElementLocated(Bylocator): 检查⻚⾯的DOM上是否存在元素
  • urlToBe(java.lang.String url): 检查当前⻚⾯的URL是⼀个特定的URL

返回值:boolean

示例:

WebDriverManager.chromedriver().setup();ChromeOptions options =newChromeOptions(); options.addArguments("--remote-allow-origins=*");WebDriver driver =newChromeDriver(options); driver.get("https://www.baidu.com"); driver.findElement(By.xpath("//*[@id=\\\"chat-textarea\\\"]")).sendKeys("胡歌");WebDriverWait wait =newWebDriverWait(driver,Duration.ofMillis(1000)); wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id=\\\"chat-submit-button\\\"]"))); driver.quit();

注意:不要混合隐式和显式等待,可能会导致不可预测的等待时间

在这里插入图片描述

3.4 浏览器导航

打开⽹站

// 更⻓的⽅法  driver.navigate().to("https://www.baidu.com");// 简洁的⽅法 driver.get("https://www.baidu.com");

浏览器的前进、后退、刷新

//后退 driver.navigate().back();//前进 driver.navigate().forward();//刷新 driver.navigate().refresh();

3.5 弹窗

之前的大部分操作都是建立在页面元素上,但是弹窗是在⻚⾯是找不到任何元素的,这种情况怎么处理?使⽤selenium提供的Alert接⼝

在这里插入图片描述

警告弹窗+确认弹窗

在这里插入图片描述
Alert alert = driver.switchTo.alert();//确认 alert.accept()//取消 alert.dismiss()
如果只有一个按钮,使用accept()和dismiss()是一样的效果

提⽰弹窗

在这里插入图片描述
Alert alert = driver.switchTo.alert(); alert.sendKeys("hello selenium"); alert.accept(); alert.dismiss();

3.5 ⽂件上传

点击文件上传按钮后会弹出系统自带的文件选择窗口,这个窗口不属于 Web 页面元素,所以 Selenium 识别不了也操作不了。
但咱们可以用 sendkeys 给上传输入框直接传入文件的路径,这样不用手动选文件,也能达到上传的目的

WebDriverManager.chromedriver().setup();ChromeOptions options =newChromeOptions(); options.addArguments("--remote-allow-origins=*");WebDriver driver =newChromeDriver(options); driver.get("file:///C:/Users/29113/AppData/Local/Temp/95a0f294-22c3-4e7c-b972-a575719f27cb_selenium-html.rar.selenium-html.rar/selenium-html/upload.html");//文件上传WebElement upload = driver.findElement(By.xpath("/html/body/div/div/input")); upload.sendKeys("C:\\Users\\29113\\AppData\\Local\\Temp\\95a0f294-22c3-4e7c-b972-a575719f27cb_selenium-html.rar.selenium-html.rar\\selenium-html\\upload.html");

3.6 浏览器参数设置

设置⽆头模式

无头模式(Headless Mode) 是浏览器的一种运行方式:它可以在不显示可视化界面(没有窗口、没有界面渲染) 的情况下,后台运行浏览器的核心功能(解析 HTML、执行 JS、发送网络请求等),默认情况下是有头模式

WebDriverManager.chromedriver().setup();ChromeOptions options =newChromeOptions();//设置无头模式 options.addArguments("--headless"); options.addArguments("--remote-allow-origins=*");WebDriver driver =newChromeDriver(options); driver.get("https://www.baidu.com");

设置浏览器加载策略

若页面资源比较多,通过driver.get方法去请求页面需要请求很长时间,就存在这样的要求:页面主要框架加载完了就继续往下执行,而不是等待所有的资源加载完成

//设置浏览器加载策略 options.setPageLoadStrategy(PageLoadStrategy.NONE);

setPageLoadStrategy有三个可选参数:

  • NONE: 完全不阻塞等待Webdriver
  • EAGER: DOM访问准备就绪,但是还是存在其他资源还在加载(注入图像…)

NORMAL: 默认值等待所有资源下载完成

在这里插入图片描述

Read more

【前端】win11操作系统安装完最新版本的NodeJs运行npm install报错,提示在此系统上禁止运行脚本

【前端】win11操作系统安装完最新版本的NodeJs运行npm install报错,提示在此系统上禁止运行脚本

🌹欢迎来到《小5讲堂》🌹 🌹这是《前端》系列文章,每篇文章将以博主理解的角度展开讲解。🌹 🌹温馨提示:博主能力有限,理解水平有限,若有不对之处望指正!🌹 目录 * 前言 * 解决方案 * 方法1:以管理员身份运行 PowerShell 并更改执行策略 * 方法2:只为当前会话临时允许 * 方法3:使用命令提示符 (CMD) * 方法4:绕过策略执行单个脚本 * 推荐解决方案 * Node.js 详细介绍 * 什么是 Node.js? * 核心特点 * 1. **非阻塞 I/O 和事件驱动** * 2. **单线程但高并发** * 架构组成 * 1. **V8 JavaScript 引擎** * 2. **LibUV 库** * 3. **核心模块** * 安装与使用

【前端】--- ES6下篇(带你深入了解ES6语法)

【前端】--- ES6下篇(带你深入了解ES6语法)

前言:ECMAScript是 JavaScript 的标准化版本,由 ECMA 国际组织制定。ECMAScript 定义了 JavaScript 的语法、类型、语句、关键字、保留字等。 ES6 是 ECMAScript 的第六个版本,于 2015 年发布,引入了许多重要的新特性,使 JavaScript 更加现代化。 进制  ES6 中增加了二进制和八进制的写法: 二进制使用前缀 '0b' 或 '0B' , 八进制使用前缀 '0o' 或 '0O'                       二进制: 前缀:   0b 或 0B:

前端引入的JS加载失败页面功能无法使用?JS加载失败的终极解决方案

前端引入的JS加载失败页面功能无法使用?JS加载失败的终极解决方案

🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Micro麦可乐的博客 🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战 🌺《RabbitMQ》专栏19年编写主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战 🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解 🌛《开源项目》本专栏主要介绍目前热门的开源项目,带大家快速了解并轻松上手使用 🍎 《前端技术》专栏以实战为主介绍日常开发中前端应用的一些功能以及技巧,均附有完整的代码示例 ✨《开发技巧》本专栏包含了各种系统的设计原理以及注意事项,并分享一些日常开发的功能小技巧 💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程 🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整 👍《Spring Security》专栏中我们将逐步深入Spring Security的各个

双剑破天门:攻防世界Web题解之独孤九剑心法(八)

双剑破天门:攻防世界Web题解之独孤九剑心法(八)

免责声明:用户因使用公众号内容而产生的任何行为和后果,由用户自行承担责任。本公众号不承担因用户误解、不当使用等导致的法律责任 **本文以攻防世界部分题为例进行演示,后续会对攻防世界大部分的web题目进行演示,如果你感兴趣请关注** 目录 一:WEB 2 二:Web_php_unserialize 三:php_rce 四:web_php_include 五:总结 1. WEB 2 2. Web_php_unserialize 3. php_rce 4. web_php_include 一:WEB 2 打开是一个php代码 代码审计 1.首先给了一段密文也就是需要解密的flag 2.然后对传进来的str进行字符串反转($_o) 3.