吊打 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

昇腾NPU运行Llama模型全攻略:环境搭建、性能测试、问题解决一网打尽

昇腾NPU运行Llama模型全攻略:环境搭建、性能测试、问题解决一网打尽

背景 最近几年,AI 大模型火得一塌糊涂,特别是像 Llama 这样的开源模型,几乎成了每个技术团队都在讨论的热点。不过,这些"巨无霸"模型虽然能力超强,但对硬件的要求也高得吓人。这时候,华为的昇腾 NPU 就派上用场了。 说实话,昇腾 NPU 在 AI 计算这块确实有两把刷子。它专门为神经网络计算设计,不仅算力强劲,功耗控制得也不错,最关键的是灵活性很好,可以根据不同场景进行裁剪。所以,用它来跑大模型推理,理论上应该是个不错的选择。 为什么偏偏选了 Llama 来测试? 说到 Llama,这玩意儿现在可是开源界的"网红"。Meta 把它完全开源出来,社区生态搞得风生水起,各种优化和适配层出不穷。 其实选择 Llama 做测试,主要有这么几个考虑:

VSCode自定义Copilot Agent与Awesome Agent

VSCode自定义Copilot Agent与Awesome Agent

本文将介绍如何在VSCode中创建自定义的Agent,以及哪里可以获取到现有的Agent模板 当我们在VSCode中使用Copilot时,可以选择以下几种模式。 Ask, Edit, Agent, 以及在2025年末时我们可以使用的全新的Plan模式。 不过除此之外,其实我们还有办法自定义属于自己的Agent。 选择右下角Agent菜单,选择Configure Custom Agents... 如选择.github\agents 则会在本工作区域中生成该路径并创建一个指定命名的agent.md文件 如果选择User Data则是会创建全局的Agent模板 在vscode中,也可以直接在文件中通过Configure Tools轻松配置所需要使用的tools,非常方便。 然后我们便可以在copilot中使用自己的Agent了. 当然,自己编写一个相对复杂的agent模板比较耗时,而awesome-copilot项目为我们提供了许多的模板,当然不止是agent,也提供了丰富的提示词模板(prompt)和指导词模板(instructions),以及

OpenCode 踩坑记:GitHub Copilot 按次计费?我的账单为何暴涨 3 倍!

OpenCode 踩坑记:GitHub Copilot 按次计费?我的账单为何暴涨 3 倍!

从发现问题到深度分析,一篇文章搞懂 OpenCode + GitHub Copilot 的正确打开方式 🌟 前言:一个意外的"惊喜" 进入2026年,朋友圈和技术群里都在讨论一个新的AI开发工具 —— OpenCode,号称是 AI 编程助手的"终极形态",支持 GitHub Copilot、Claude、GPT-4 等多种模型,还能自动执行多步任务。 作为一个爱折腾的程序员,我立马下载试用。我有 GitHub Copilot 企业订阅,而且OpenCode还支持,用起来应该不花钱吧? 结果一周后,我收到了公司 IT 部门的"温馨提醒" 📧: “您的 Copilot 使用量是团队平均水平的 3 倍,请注意合理使用…” 什么情况??我明明只是让