当前位置: 首页 > news >正文

Java + Seleium4.X + TestNG自动化技术

系列文章目录


文章目录

  • 系列文章目录
  • 前言
  • 一、 Java版Selenium自动化测试框架介绍和原理
    • 1.1 什么是Seleium
    • 1.2 特点
    • 1.3 注意点
  • 二、安装Seleium+Chrome环境 + 创建Maven项目
    • 2.1 安装Seleium + Chrome环境
    • 2.2 Maven环境
  • 三、Selenium4.X UI元素定位实战
    • 3.1 ID选择器
    • 3.2 Name选择器
    • 3.3 linkText选择器
    • 3.4 partialLinkText选择器
    • 3.5 Class选择器
    • 3.6 CSS选择器
    • 3.7 TagName选择器
    • 3.8 XPath选择器
  • 四、 WebDriver基础操作
    • 4.1 WebDriver对象API操作
    • 4.2 WebElement对象API操作
    • 4.3 浏览器API操作
    • 4.4 鼠标事件操作
    • 4.5 模拟键盘输入操作
    • 4.6 显示等待和隐式等待
  • 五、Selenium4.X窗口、下拉框操作
    • 5.1 Selenium4.X的窗口切换实战
    • 5.2 项目实战
    • 5.3 Selenium4.X的快照截图
    • 5.4 下拉框Select处理
    • 5.5 弹窗Alert处理
  • 六、Selenium4.X自动化测试多案例实战
    • 6.1 UI自动化测试用例编写
    • 6.2 豆瓣网自动化测试实战


前言

  • Selenium是最受欢迎的Web应用程序自动化测试工具之一。
  • 通过学习Selenium,可以编写自动化测试脚本,用于自动执行各种任务,例如验证功能、测试用户界面、模拟用户交互
  • 大大提高测试效率,减少手动测试的工作量

一、 Java版Selenium自动化测试框架介绍和原理

1.1 什么是Seleium

Selenium自动化测试框架

  • 是一个用于Web应用程序测试的自动化测试工具

  • 支持多种浏览器(如Chrome、Firefox、Safari等)和操作系统(如Windows、Linux、macOS等),

  • 提供了一个丰富的API,允许用户模拟真实用户的交互行为,如点击、输入、提交等

  • 官网:https://www.selenium.dev

1.2 特点

  • 跨平台与多浏览器支持:Selenium可以在不同的操作系统和浏览器上运行,提供了广泛的兼容性
  • 开源与免费:Selenium是一个开源项目,用户可以免费地使用其中的工具和库
  • 强大的API:Selenium提供了丰富的API,允许用户进行复杂的页面操作和验证
  • 支持自动化测试:Selenium可以模拟真实用户的交互行为,从而进行自动化测试,提高测试效率
  • 集成与扩展性:可以与其他测试工具(如Jenkins)和编程语言(如Python、Java等)集成,提供了很好的扩展性

1.3 注意点

  • 环境搭建浏览器版本和驱动版本对应关系
    • 安装Selenium库,不同语言采用不同依赖包安装
    • 下载与浏览器对应的WebDriver,如ChromeDriver或GeckoDriver,并确保它们与浏览器版本匹配
    • 浏览器版本一定要和驱动版本一一对应,不然存在不兼容问题

二、安装Seleium+Chrome环境 + 创建Maven项目

2.1 安装Seleium + Chrome环境

前置:环境使用的JDK21版本+Maven3.8 +IDEA旗舰版

  • 驱动相关注意事项(如果驱动版本太新,可以降低版本验证)

    • 浏览器版本(保证驱动版本和浏览器版本前三位相同 134.0.6998.XXX)
    • 在这里插入图片描述
  • 相关驱动版本下载地址(如果浏览器版本太新找不到驱动,可以降低浏览器版本,如果遇到selenium兼容性问题,统一降低版本)
    • https://registry.npmmirror.com/binary.html?path=chromedriver
    • https://googlechromelabs.github.io/chrome-for-testing/#stable

2.2 Maven环境

配置环境不多说,如下参考文档
手把手教你配置Maven环境并用IDEA创建一个Maven工程

  • 添加依赖
  <dependencies><!-- Selenium --><dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>4.10.0</version></dependency></dependencies>

添加之后爆红可以刷新加载
在这里插入图片描述

三、Selenium4.X UI元素定位实战

主程序入口,前置步骤,后续案例都在这里调用

public class Main {public static void main(String[] args) throws Exception {//指定驱动路径System.setProperty("webdriver.chrome.driver","D:\\developer_tools\\Broswer_Driver\\Chromedriver\\chromedriver-win64\\chromedriver.exe");// 谷歌驱动ChromeOptions options = new ChromeOptions();// 允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver = new ChromeDriver(options);//窗口最大化webDriver.manage().window().maximize();}

3.1 ID选择器

元素定位方法说明

  • 在使用webdriver进行元素定位时,通常用findElementfindElements方法结合By类返回元素句柄来定位元素

  • findElement() 方法返回一个元素, 如果没有找到,会抛出一个异常 NoElementFindException()

  • findElements()方法返回多个元素, 如果没有找到,会返回空数组, 不会抛出异常

  • ID元素定位

    • HTML中的每个元素都可以设置一个唯一的ID属性。通过该属性 可以精确地定位到页面上的某个元素
    • 在Selenium中,使用findElement(By.id(“id的值”));方法可以根据元素的ID进行定位
  • 注意事项

    • ID应该是唯一的,因此在页面上不应该有两个或更多的元素具有相同的ID
    • 如果元素的ID发生了改变,或者页面上没有该ID的元素,那么定位会失败
public static void idTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);WebElement element = webDriver.findElement(By.id("kw"));element.sendKeys("csdn");}

3.2 Name选择器

  • Name元素定位

    • 在HTML中,某些元素(如<input>, <button>, <select>等)可以设置一个Name属性
    • 虽然Name属性不必唯一,但在某些情况下,它可以用于定位特定的元素
    • 在Selenium中,使用findElement(By.name(“name的值”));方法可以根据元素的Name属性进行定位
  • 注意事项

    • Name属性不必唯一,可能存在多个元素具有相同的Name,默认只会返回第一个匹配的元素
    • 如果页面上的元素没有设置Name属性,或者Name属性的值发生了改变,那么定位会失败
public static void nameTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);WebElement element = webDriver.findElement(By.name("wd"));element.sendKeys("csdn");}

3.3 linkText选择器

Selenium4元素定位之链接方式

  • 通过超链接上的文字信息来定位元素,包括通过链接的全部文字和部分文字进行定位

  • 链接的全部文字定位

    • 当链接的完整文本是唯一的,想要定位这个链接时,可以使用By.linkText方法
    • By.linkText("完整的链接文本")用于查找页面上文字完全匹配的链接
 public static void LinkTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);WebElement element = webDriver.findElement(By.linkText("新闻"));String text = element.getText();System.out.println(text);element.click();}

3.4 partialLinkText选择器

链接的部分文字定位

  • 当链接的文本不是唯一的,想基于部分文本来定位链接时,可以使用By.partialLinkText方法
  • By.partialLinkText("部分链接文本")用于查找页面上文字包含指定文本的链接
 public static void partialLinkTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);WebElement element = webDriver.findElement(By.partialLinkText("贴吧"));element.click();}

3.5 Class选择器

  • Class方式
    • 通过属性class定位元素,查找一个或一组显示效果相同的页面元素
    • driver.findElement(By.className('class属性'));
 public static void classTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);List<WebElement> elements = webDriver.findElements(By.className("title-content-title"));System.out.println("size ===="  + elements.size());for (WebElement element : elements) {String text = element.getText();System.out.println(text);}}

3.6 CSS选择器

Selenium4元素定位之CSS选择器方式

  • selenium中的css定位,是通过css选择器来定位到具体元素,css选择器来自于css语法
  • css相较与xpath选择元素:表达式更加简洁,一般情况css的运行速度是优于xpath的
  • 常见的选择器包括:
    • 标签:直接使用标签名,如下列:p
    • 类(class):“.”(英文句号)+class值
    • id:“#”+id值*
    • 通配符:意为匹配所有元素, 用“*”表示

使用CSS选择器定位元素案例说明

// 通过类名定位  
WebElement elementByClassName = driver.findElement(By.cssSelector(".class-name"));  
// 通过ID定位(虽然通常使用By.id更直接)  
WebElement elementById = driver.findElement(By.cssSelector("#element-id"));  
// 通过标签名定位  
WebElement elementByTagName = driver.findElement(By.cssSelector("div"));  
// 通过属性定位  
WebElement elementByAttribute = driver.findElement(By.cssSelector("input[name='input-name']")); 

案例

public static void cssTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);List<WebElement> elements = webDriver.findElements(By.cssSelector("#s-hotsearch-wrapper > div > a.hot-title > div"));System.out.println("size ===" + elements.size());for (WebElement element : elements) {String text = element.getText();System.out.println(text);}}

3.7 TagName选择器

Selenium4元素定位之TagName选择器方式

  • 标签名定位方式主要用于匹配多个页面元素的情况,将找到的页面元素对象进行计数、遍历

  • HTML的本质就是通过tag来定义实现不同的功能,每一个元素本质上也是一个tag

  • 通过方法driver.findElement(By.tagName(“标签名称”)); 进行操作

public static void tarNameTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);List<WebElement> elements = webDriver.findElements(By.tagName("a"));for (WebElement element : elements) {String text = element.getText();String href = element.getAttribute("href");System.out.println(text);}}

3.8 XPath选择器

Selenium4.X元素定位之XPath案例实操**

  • 什么是XPath

    • XPath(XML Path Language)是一种在XML文档中查找信息的语言,也可以用于HTML
    • XPath提供了非常强大的定位能力,可以定位到几乎任何元素

1.路径

1). 绝对路径:
语法:以单斜杠开头逐级开始编写,不能跳级。如:/html/body/div/p[1]/input
2). 相对路径
语法:以双斜杠开头,双斜杠后边跟元素名称,不知元素名称可以使用*代替。
如: //input 与 // *

路径结合属性
语法:在Xpath中,所有的属性必须使用@符号修饰 如://[@id=‘id值’]
路径结合逻辑(多个属性)
语法://
[@id=“id值” and @属性=‘属性值’]
路径结合层级
语法://*[@id=‘父级id属性值’]/input

 public static void xpathTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);List<WebElement> elements = webDriver.findElements(By.xpath("//*[@id=\"head\"]"));for (WebElement element : elements) {String text = element.getText();System.out.println(text);}}

四、 WebDriver基础操作

4.1 WebDriver对象API操作

方法描述
get(String url)访问目标 url 地址,打开网页
getCurrentUrl()获取当前页面 url 地址
getTitle()获取页面标题
getPageSource()获取页面源代码
close()关闭浏览器当前打开的窗口
quit()关闭浏览器所有的窗口
findElement(by)查找单个元素
findElements(by)查到元素列表,返回一个集合
getWindowHandle()获取当前窗口句柄
getWindowHandles()获取所有窗口的句柄
 public static void webdriverTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);String currentUrl = webDriver.getCurrentUrl();System.out.println(currentUrl);String title = webDriver.getTitle();System.out.println("title: " + title);String pageSource = webDriver.getPageSource();System.out.println(pageSource);TimeUnit.SECONDS.sleep(2);webDriver.close();webDriver.quit();webDriver.findElement(By.id("kw")).sendKeys("csdn");Set<String> windowHandles = webDriver.getWindowHandles();for (String handle : windowHandles) {System.out.println("窗口句柄" + handle);}}

4.2 WebElement对象API操作

元素对象API操作语法

  • WebElement对象常用API
方法说明
click点击对象
sendKeys在对象上模拟按键输入
clear清除对象输入的文本内容
submit提交,比如表单对象
getAttribute获取元素的指定属性
getText用于获取元素的文本信息
 public static void webElementTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);webDriver.findElement(By.id("kw")).sendKeys("博客园");TimeUnit.SECONDS.sleep(2);webDriver.findElement(By.id("kw")).clear();TimeUnit.SECONDS.sleep(2);webDriver.findElement(By.id("kw")).sendKeys("csdn");TimeUnit.SECONDS.sleep(2);webDriver.findElement(By.id("su")).click();}

4.3 浏览器API操作

  • 需求

    • 浏览器操作网页,有前进、后退,不同网页直接切换,窗口最大化、刷新等
    • 通过Selenium的api完成上述的操作案例
  • 浏览器案例

    • API语法
    方法说明
    back模拟浏览器后退按钮
    forward模拟浏览器前进按钮
    refresh刷新页面(F5)
    maximize浏览器最大化
    setSize浏览器宽高
    manage( ).window( ).setSize( )设置浏览器的大小
public static void browserTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);webDriver.findElement(By.id("kw")).sendKeys("博客园");webDriver.findElement(By.id("su")).click();TimeUnit.SECONDS.sleep(2);WebDriver.Navigation navigate = webDriver.navigate();navigate.refresh();TimeUnit.SECONDS.sleep(2);navigate.back();TimeUnit.SECONDS.sleep(2);navigate.forward();

4.4 鼠标事件操作

  • Selenium的鼠标事件

    • 鼠标操作主要是通过Actions类来实现的,该类提供了一系列模拟鼠标操作的方法
    • 包括有 右击、双击、悬停、拖动等
  • 鼠标案例API语法

    方法说明
    contextClick( )右击
    clickAndHold( )鼠标点击并控制
    doubleClick( )双击
    dragAndDrop( )拖动
    release( )释放鼠标
    perform( )执行所有Actions中存储的行为
  public static void mouseTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);webDriver.findElement(By.cssSelector("#kw")).sendKeys("csdn");TimeUnit.SECONDS.sleep(2);webDriver.findElement(By.cssSelector("#su")).click();TimeUnit.SECONDS.sleep(2);WebElement element = webDriver.findElement(By.cssSelector("#s_tab_inner > a.s-tab-item.s-tab-item_1CwH-.s-tab-note_2zG_i.s-tab-note > span"));TimeUnit.SECONDS.sleep(2);//鼠标右键Actions action = new Actions(webDriver);action.moveToElement(element).contextClick().perform();}

4.5 模拟键盘输入操作

什么是模拟键盘

  • 利用ActionsKeys类来模拟键盘操作,包括文本输入、按键和组合键序列,增强自动化脚本的用户交互能力

  • Keys枚举提供了方便的表示键盘上按键的方法,而Actions类则用于构建复杂的交互序列

  • 这两者结合,允许在Web自动测试中模拟几乎任何类型的键盘操作

发送特殊字符

  • sendKeys 使用Keys类中的常量,可以发送特殊字符或按键事件,sendKeys接收可变参数

sendKeys(Keys.BACK_SPACE) 回格键(BackSpace)、sendKeys(Keys.SPACE) 空格键 (Space)
sendKeys(Keys.TAB) 制表键 (Tab)、sendKeys(Keys.ESCAPE) 回退键(Esc)
sendKeys(Keys.ENTER) 回车键(Enter)、sendKeys(Keys.F1) 键盘 F1
sendKeys(Keys.CONTROL,‘a’) 全选(Ctrl+A)、sendKeys(Keys.CONTROL,‘c’) 复制(Ctrl+C)
sendKeys(Keys.CONTROL,‘x’) 剪切(Ctrl+X)、sendKeys(Keys.CONTROL,‘v’) 粘贴(Ctrl+V)

 public static void keyboardTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);WebElement element = webDriver.findElement(By.cssSelector("#kw"));element.sendKeys("csdny");TimeUnit.SECONDS.sleep(2);//删除一个字符element.sendKeys(Keys.BACK_SPACE);TimeUnit.SECONDS.sleep(2);element.sendKeys(Keys.SPACE);element.sendKeys("博客");element.sendKeys(Keys.ENTER);}

4.6 显示等待和隐式等待

  • 需求

    • Web应用通常通过异步加载(如Ajax)来动态更新页面内容,页面元素可能不是立即可用的

    • 当自动化测试脚本尝试访问或操作这些元素时,如果没有等待机制,可能会遇到定位失败、元素状态不正确等异常

    • Selenium4等待主要解决以下问题:

      • 元素加载延迟

        • 当页面上的某些元素是通过异步请求(如Ajax)加载的,这些元素可能不会立即出现在DOM中
        • 网络波动或服务器响应延迟,页面上的某些内容可能需要一些时间才能加载
        • 如果没有等待机制,测试脚本可能会在元素实际可用之前访问它,导致定位失败
      • 依赖关系

        • 测试脚本中的操作可能依赖于前一步的结果或内容
        • 例如,一个表单提交后,可能需要等待新页面加载完成才能继续执行后续操作
      • 页面更新

        • JavaScript可能会动态更改页面内容,如添加、删除或修改元素

        • 如果没有等待,测试脚本可能会错过这些变化,导致测试失败

  • Selenium 等待元素出现的方式有以下三种

    • 强制等待
      • 即线程休眠,在代码中强制当前正在执行的线程休眠(暂停执行)不管元素有没出现都固定时间 TimeUnit.SECONDS.sleep(2);
    • 显式等待(Explicit Wait)
      • 通俗说就是死等,不灵活的等待,在指定的时间内一定要等到某个元素的出现或可操作的状态
      • 如果等不到,就一直等,直到在规定的时间之内都要操作的元素仍没找到,就抛出异常
      • 可以针对特定的元素或一组元素进行等待,提供了更灵活的等待机制,可以等待复杂的条件
    • 隐式等待 (Implicit Wait)
      • 设置全局等待时间,全部查找都会生效,驱动初始化后就可以配置,在指定时间内轮询DOM,直到找到元素或超时
      • 一旦设置,在整个WebDriver对象实例的生命周期内都有效
      • 适用于等待整个页面加载完毕

隐式等待案例

 public static void impwaitTest(WebDriver webDriver){webDriver.get("https://www.baidu.com");//隐式等待webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));//使用一个不存在的元素idWebElement element = webDriver.findElement(By.id("sd"));element.sendKeys("csdn");}

显示等待案例

public static void waitTest(WebDriver webDriver){webDriver.get("https://www.baidu.com");//显示等待WebDriverWait wait = new WebDriverWait(webDriver, Duration.ofSeconds(10));wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("kw")));WebElement element = webDriver.findElement(By.id("kw"));element.sendKeys("csdn");}

五、Selenium4.X窗口、下拉框操作

5.1 Selenium4.X的窗口切换实战

  • 需求

    • 自动化测试过程中会有打开不同网页的操作
    • 网页操作时会打开新窗口,不同窗口需要如何进行切换?
  • 不同窗口的切换

    • 自动化脚本通过识别浏览器窗口的属性用句柄handle来识别不同窗口
    • 窗口句柄handle是窗口的唯一标识,是窗口的唯一ID
    • 通过 webDriver.getWindowHandles() 获取窗口全部具柄
    • 默认是第一个打开窗口,通过 webDriver.switchTo().window() 传入某个窗口句柄,切换到对应窗口
public static void windowTest(WebDriver webDriver)throws  InterruptedException {webDriver.get("https://www.baidu.com");//隐式等待webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();//获取全部窗口的句柄Set<String> windowHandles = webDriver.getWindowHandles();String newHandle = "";for (String windowhandle : windowHandles) {System.out.println("windowhandle: " + windowhandle);//记录最后一个句柄newHandle = windowhandle;}//切换窗口  如果没调用切换 则对应的页面操作会失败webDriver.switchTo().window(newHandle);String text = webDriver.findElement(By.cssSelector("#headline-tabs > ul > li > a")).getText();System.out.println("text: " + text);}

5.2 项目实战

什么是 iframe

  • iframe(Inline Frame)是HTML文档中的一个元素,允许在当前HTML页面中嵌入另一个HTML页面

  • 其基本的用途是将另一个HTML文档嵌入到主文档中

  • 就是一个网页可以嵌套到另一个网页中,可以嵌套很多层

  • 使用selenium 操作浏览器时,如果需要操作iframe中的元素,首先需要切换到对应的内联框架中

  • Selenium 给提供了三个重载的方法,进行操作iframe
// 方法一:通过 iframe的索引值,在页面中的位置
webDriver.switchTo().frame(index);
// 方法二:通过 iframe 的name 或者id
webDriver.switchTo().frame(nameOrId);
// 方法三:通过iframe 对应的webElement        
webDriver.switchTo().frame(frameElement);
public static void iframeTest(WebDriver webDriver)throws InterruptedException {webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));webDriver.get("https://www.126.com");WebElement element = webDriver.findElement(By.xpath("//div[@class='g-bd cnt-box-include']/div[@class='g-bd']/div[@class='m-cnt']"));webDriver.switchTo().frame(element);//定位账号输入框webDriver.findElement(By.xpath("//div[@class='u-input box']/input[@name='email']")).sendKeys("lao123");webDriver.findElement(By.xpath("//div[@class='inputbox']/div[@class='u-input box']/input[@name='password']")).sendKeys("123456");}

5.3 Selenium4.X的快照截图

  • 什么是Selenium的快照截图

    • 自动化测试的时候,没有人工进行观看,用例执行失败如何进行发现?
    • 如果遇到有错误信息等,如何保存当前页面的截图,方便后续排查?
    • 快照截图功能是指Selenium自动化测试工具在测试过程中捕获浏览器窗口当前显示内容的图像
    • 是Selenium在测试或调试过程中,为了保存当前浏览器窗口的可见内容而提供的一种功能
    • 通常用于分析页面布局、验证页面元素的存在或状态,在测试失败时捕获页面状态以供后续分析
  • 网页快照截图

    • 通过API (TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE)
 public static void screenTest(WebDriver webDriver)throws Exception {webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));webDriver.get("https://www.baidu.com");webDriver.findElement(By.id("kw")).sendKeys("博客园");//点击搜索webDriver.findElement(By.cssSelector("#su")).click();TimeUnit.SECONDS.sleep(5);File file = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE);//存储本地String filPath = "C:\\Users\\岳不群\\Desktop\\class\\screen.png";File target = new File(filPath);//保存到本地try(FileOutputStream out = new FileOutputStream(target);FileInputStream inp = new FileInputStream(file);){byte[] buffer = new byte[1024];int total = 0;while ((total = inp.read(buffer))!=-1){out.write(buffer,0,total);}}}

5.4 下拉框Select处理

自动化测试里面的下拉框操作

  • 在网页设计中,下拉框(也被称作下拉列表或者选择框)是一种用户界面控件

  • 下拉框通常在被点击时显示其包含的所有选项列表,在用户选择某一选项后,列表会收回,只显示用户所选择的那个选项

  • 如果一个页面元素是一个下拉框(select),对应下拉框的操作,selenium有专门的类 Select 进行处理

  • 其中包含了单选和多选下拉框的各种操作,如获得所有的选项、选择某一项、取消选中某一项、是否是多选下拉框等

  • 构造函数:
    • Select(WebElement element): 创建一个新的 Select 对象,用于操作指定的 元素
  • 选择选项的方法:
    • void selectByIndex(int index): 根据索引选择选项(索引从 0 开始)
    • void selectByValue(String value): 根据选项的 value 属性值选择选项
    • void selectByVisibleText(String text): 根据选项的可见文本选择选项
  • 取消选择选项的方法 (适用于多选下拉框):
    • void deselectAll(): 取消选择所有已选中的选项
    • void deselectByIndex(int index): 根据索引取消选择选项
    • void deselectByValue(String value): 根据选项的 value 属性值取消选择选项
    • void deselectByVisibleText(String text): 根据选项的可见文本取消选择选项
  • 获取选项的方法:
    • List getOptions(): 获取下拉框中的所有选项。
    • List getAllSelectedOptions(): 获取下拉框中所有已选中的选项
    • WebElement getFirstSelectedOption(): 获取下拉框中第一个已选中的选项
  • 检查是否为多选下拉框:
    • boolean isMultiple(): 返回下拉框是否支持多选
public static void selectTest(WebDriver webDriver) throws InterruptedException {webDriver.get("file:///C:/Users/%E5%B2%B3%E4%B8%8D%E7%BE%A4/Desktop/select.html");//创建一个显示等待WebDriverWait wait = new WebDriverWait(webDriver, Duration.ofSeconds(10));wait.until(ExpectedConditions.elementToBeClickable(By.id("mySelect")));//找到元素再点击WebElement element = webDriver.findElement(By.id("mySelect"));element.click();Select select = new Select(element);List<WebElement> options = select.getOptions();for (WebElement option : options) {System.out.println(option.getText());}TimeUnit.SECONDS.sleep(2);//根据选项的所见文本进行选择select.selectByVisibleText("csdn");//根据索引位置选择select.selectByIndex(1);TimeUnit.SECONDS.sleep(2);select.selectByValue("5");System.out.println(select.isMultiple());}

5.5 弹窗Alert处理

什么是Alert

  • 操作alert、confirm弹出框,可以通过Alert 对象来进行操作,Alert类包含了确认、取消、输入和获取弹出窗内容。
  • Alert对应属性和方法
方法描述
alert.getText()获取弹出框内容
alert.accept()接受弹窗的提示,相当于点击确认按钮
alert.dismiss()取消提示窗
alert.sendKeys(String s)给弹窗输入内容

网页中常用的弹出框有三种:

  • alert 警告框
  • confirm 确认框
  • prompt 提示框

同弹窗使用流程

  • 触发弹出框

    • 弹出框是由页面上的某些操作触发的,比如点击一个按钮或执行某些JavaScript代码。
    • 需要确保在执行下一步之前弹出框已经显示
  • 切换到弹出框

    • 使用WebDriverswitchTo().alert()方法来切换到弹出框
    • 返回一个Alert对象,可以通过这个对象与弹出框进行交互

Alert alert = driver.switchTo().alert();

处理alert弹出框

  • alert弹出框通常只包含一条消息和一个“确定”按钮,可以使用alert.accept()方法来点击“确定”按钮

alert.accept();

处理confirm弹出框

  • confirm弹出框包含一个消息、一个“确定”按钮和一个“取消”按钮
  • 可以使用alert.accept()来点击“确定”按钮,或者使用alert.dismiss()来点击“取消”按钮
// 点击“确定”按钮  
alert.accept();  // 或者点击“取消”按钮  
alert.dismiss();
 public static void alertTest(WebDriver webDriver) throws InterruptedException {webDriver.get("file:///C:/Users/%E5%B2%B3%E4%B8%8D%E7%BE%A4/Desktop/select.html");//创建显示等待WebDriverWait wait = new WebDriverWait(webDriver, Duration.ofSeconds(2));wait.until(ExpectedConditions.elementToBeClickable(By.id("alert_btn"))).click();//处理alertAlert alert = webDriver.switchTo().alert();System.out.println(alert.getText());TimeUnit.SECONDS.sleep(2);alert.accept();//处理confirmwebDriver.findElement(By.id("confirm_btn")).click();//切换Alert confirm = webDriver.switchTo().alert();TimeUnit.SECONDS.sleep(2);confirm.dismiss();}

六、Selenium4.X自动化测试多案例实战

6.1 UI自动化测试用例编写

UI自动化测试用例编写规范

  • 一个脚本对应一个完整场景
    • 每个自动化测试脚本应覆盖一个完整的用户场景,例如从用户登录到退出系统的整个过程。
  • 单一功能点验证
    • 每个脚本应专注于验证一个特定的功能点,避免在一个脚本中验证多个功能。
  • 正向逻辑验证为主
    • 优先验证功能的正向逻辑,避免过度考虑逆向逻辑的验证,以减少脚本的复杂性和脆弱性。
  • 脚本独立性
    • 确保每个脚本都是独立的,不依赖于或影响其他脚本的执行。
  • 数据还原
    • 如果测试过程中修改了数据,测试结束后应对数据进行还原,保持测试环境的清洁。
  • 验证点明确
    • 在脚本中只针对明确的验证点进行验证,避免对整个脚本的每一步都进行验证。
  • POM(Page Object Model)结构
    • 设计遵循POM结构,将用例层、业务逻辑层和Page层明确分离。
  • 页面设计规则
    • 每个页面一个类,类名以Page结尾;页面辅助控件和逻辑设计为接口,并提供默认实现。
  • 参数封装
    • 除简单逻辑外,业务逻辑的参数使用Java Bean和枚举封装,以适应产品设计的变化。
  • 状态码和文案
    • 使用枚举定义状态码、产品特定文案等,以规范入参

6.2 豆瓣网自动化测试实战

  • 测试用例一:用户登录功能

    • 测试目标:验证用户登录功能的正确性。
    • 前置条件:豆瓣网已注册用户,存在有效账号和密码。
    • 测试步骤
      • 打开豆瓣网首页。
      • 点击登录按钮,进入登录页面。
      • 输入正确的用户名和密码。
      • 点击登录按钮。
    • 预期结果
      • 成功登录后,跳转到用户主页或上次访问的页面。
      • 页面右上角显示登录用户的信息。
    • 实际结果:记录实际登录后的页面跳转情况和用户信息显示情况。
  • 测试用例二:电影搜索功能

    • 测试目标:验证电影搜索功能的正确性。
    • 前置条件:豆瓣网存在电影搜索功能。
    • 测试步骤
      • 打开豆瓣网首页。
      • 进入电影搜索页面。
      • 输入电影名称或关键词。
      • 点击搜索按钮。
    • 预期结果
      • 搜索结果页面显示与输入关键词相关的电影列表。
      • 电影列表包含电影标题、评分、导演、主演等信息。
    • 实际结果:记录实际搜索结果页面的内容和展示情况。
  • 测试用例三:电影评论功能

    • 测试目标:验证电影评论功能的正确性。
    • 前置条件:已登录豆瓣网账号,选择一部电影进入详情页面。
    • 测试步骤
      • 进入电影详情页面。
      • 滚动到评论区域,查看已有评论。
      • 点击写评论按钮,输入评论内容。
      • 点击提交按钮。
    • 预期结果
      • 评论成功提交后,在页面上能够看到新添加的评论。
      • 新评论包含评论者头像、昵称、评论内容、时间等信息。
    • 实际结果:记录评论提交后的页面显示情况和新评论的展示情况。
  • 测试用例四:豆瓣读书模块功能

    • 测试目标:验证豆瓣读书模块功能的正确性。
    • 前置条件:豆瓣网存在读书模块,包含书籍搜索、书籍详情、书评等功能。
    • 测试步骤(以书籍搜索为例):
      • 进入豆瓣读书页面。
      • 在搜索框中输入书籍名称或关键词。
      • 点击搜索按钮。
    • 预期结果
      • 搜索结果页面显示与输入关键词相关的书籍列表。
      • 书籍列表包含书籍封面、标题、作者、评分等信息。
    • 实际结果:记录实际搜索结果页面的内容和展示情况。
  • 测试用例五:豆瓣同城活动功能

    • 测试目标:验证豆瓣同城活动功能的正确性。
    • 前置条件:豆瓣网存在同城活动模块,包含活动搜索、活动详情、报名等功能。
    • 测试步骤(以活动搜索为例):
      • 进入豆瓣同城页面。
      • 在搜索框中输入活动类型或关键词。
      • 点击搜索按钮。
    • 预期结果
      • 搜索结果页面显示与输入关键词相关的活动列表。
      • 活动列表包含活动名称、时间、地点、参与人数等信息。
    • 实际结果:记录实际搜索结果页面的内容和展示情况。

组件代码封装

package net.xdclass;import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;public class SeleiumBase {protected WebDriver webDriver;//初始化方法public void setUp() {//指定驱动路径System.setProperty("webdriver.chrome.driver","D:\\developer_tools\\Broswer_Driver\\Chromedriver\\chromedriver-win64\\chromedriver.exe");// 谷歌驱动ChromeOptions options = new ChromeOptions();// 允许所有请求options.addArguments("--remote-allow-origins=*");webDriver = new ChromeDriver(options);webDriver.manage().window().maximize();}/*** 退出浏览器*/public void tearDown() {if (webDriver != null) {webDriver.quit();}}
}

用例编写

package net.xdclass;import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;import java.time.Duration;public class TestReadBookPage extends SeleiumBase{/*** 在所有测试执行前进行初始化操作。* 初始化浏览器驱动,设置隐式等待时间,并导航到豆瓣首页。*/@BeforeClasspublic void setupClass(){setUp();webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));webDriver.get("https://www.douban.com/");}/*** 在所有测试执行后进行清理操作。* 主要是为了调用父类的清理方法,确保资源正确释放。*/@AfterClasspublic void tearDownClass(){tearDown();}/*** 测试豆瓣首页的标题是否包含"豆瓣"。* 该测试优先级为1,确保在其他测试之前执行。*/@Test(priority=1)public void testHomePageTitle(){String title = webDriver.getTitle();System.out.println(title);Assert.assertTrue(title.contains("豆瓣"),"标题不包括豆瓣");}/*** 从首页点击进入读书页面,验证是否成功进入豆瓣读书页面。* 该测试依赖于testHomePageTitle测试,只有在首页标题测试通过后才会执行。*/@Test(priority=2)public void testEnterBookPage(){webDriver.findElement(By.xpath("//*[@id=\"anony-nav\"]/div[1]/ul/li[1]/a")).click();//切换窗口webDriver.getWindowHandles().forEach(window -> webDriver.switchTo().window(window));String currentUrl = webDriver.getCurrentUrl();System.out.println("currentUrl: " + currentUrl);Assert.assertTrue(currentUrl.contains("book.douban.com"), "没有进入到豆瓣读书页面");}/*** 测试搜索功能,搜索关键词"斗破苍穹",验证是否进入搜索结果页面。* 该测试优先级为3,旨在测试搜索功能的基本可用性。*/@Test(priority=3)public void testSerarchPage(){webDriver.findElement(By.id("inp-query")).sendKeys("斗破苍穹");webDriver.findElement(By.xpath("//*[@id=\"db-nav-book\"]/div[1]/div/div[2]/form/fieldset/div[2]/input")).click();String title = webDriver.getTitle();System.out.println(title);Assert.assertTrue(title.contains("斗破苍穹"),AssertMessage.ERROR_TITLE_MESSAGE);}/*** 验证搜索结果中是否包含"斗破苍穹"这本书。* 该测试依赖于testSearchPage,确保搜索功能正常后验证搜索结果。*/@Test(priority=4)public void testSearchResult(){WebElement element = webDriver.findElement(By.xpath("//*[@id=\"root\"]/div/div[2]/div[1]/div[1]/div[3]/div/div/div[1]"));String text = element.getText();Assert.assertTrue(text.contains("斗破苍穹"),"标题不对");}
}

相关文章:

Java + Seleium4.X + TestNG自动化技术

系列文章目录 文章目录 系列文章目录前言一、 Java版Selenium自动化测试框架介绍和原理1.1 什么是Seleium1.2 特点1.3 注意点 二、安装SeleiumChrome环境 创建Maven项目2.1 安装Seleium Chrome环境2.2 Maven环境 三、Selenium4.X UI元素定位实战3.1 ID选择器3.2 Name选择器3.…...

Spark SQL核心概念与编程实战:从DataFrame到DataSet的结构化数据处理

一、Spark-SQL是什么 Spark SQL 是 Spark 用于结构化数据(structured data)处理的 Spark 模块。 二、Hive and SparkSQL SparkSQL 的前身是 Shark&#xff0c;Shark是给熟悉 RDBMS 但又不理解 MapReduce 的技术人员提供的快速上手的工具。 Hive 是早期唯一运行在 Hadoop 上的 S…...

electron-vite 应用打包自定义图标不显示问题

// 修改electron-builder.yml ... win:executableName: xxx //可执行文件名称icon: build/icon.ico //你的图标路径 ...打包后&#xff0c;自定义图标不显示原因: 1 cannot execute causeexit status 2&#xff0c;安装包无法生成 用管理员身份运行&#xff0c;win11右击开始…...

AI中Token的理解与使用总结

AI中Token的理解与使用总结 什么是Token 在AI领域,特别是自然语言处理(NLP)中,Token是指将文本分割成的最小处理单元。Tokenization(分词)是将原始文本分解为Token的过程。 Token的几种形式 单词级Token:以单词为基本单位 示例:“Hello world” → [“Hello”, “world”…...

C++/SDL 进阶游戏开发 —— 双人塔防(代号:村庄保卫战 14)

&#x1f381;个人主页&#xff1a;工藤新一 &#x1f50d;系列专栏&#xff1a;C面向对象&#xff08;类和对象篇&#xff09; &#x1f31f;心中的天空之城&#xff0c;终会照亮我前方的路 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 文章目录 二…...

全栈量子跃迁:当Shor算法破解RSA时,我们如何用晶格密码重构数字世界的信任基岩?

一、量子威胁的降维打击 1. Shor算法的毁灭性力量 # Shor算法量子电路简化示例&#xff08;Qiskit实现&#xff09; from qiskit import QuantumCircuit from qiskit.circuit.library import QFTdef shor_circuit(n: int, a: int) -> QuantumCircuit:qc QuantumCircuit(2…...

python实战项目65:drissionpage采集boss直聘数据

python实战项目65:drissionpage采集boss直聘数据 一、需求简介二、流程分析三、完整代码一、需求简介 boss直聘网站近期改版,改版之后代码需要做相应的升级维护。drissionpage采集网页数据是一种不错的方式,笔者认为比Selenium好用,使用方法大家可以自行查阅资料。boss直聘…...

常用的性能提升手段--提纲

上一篇文章里,介绍了提升性能的一种优化手段:池化。 这篇文章来归纳整理一下其他的常见的提升性能的手段 1. 缓存 (Caching) 缓存可以说是计算机领域的万金油了,它无处不在。 举个最简单的例子,CPU -> L1,L2,L3 Cache -> 内存 。 CPU的处理速度要比内存快几个数量…...

天梯——现代战争

第一次做的时候&#xff0c;直接暴力&#xff0c;显然最后超时。 暴力代码如下&#xff1a; #include<bits/stdc.h> using namespace std; const int N10005; bool mark1[N]{0},mark2[N]{0}; int p[N][N]; int main(){int n,m,k,a,b;cin>>n>>m>>k;fo…...

Codeforces Round 1021 (Div. 2) D. Baggage Claim(建图)

每周五篇博客&#xff1a;&#xff08;4/5&#xff09; https://codeforces.com/contest/2098/problem/D 题意 每个机场都有一个行李索赔区&#xff0c;巴尔贝索沃机场也不例外。在某个时候&#xff0c;Sheremetyevo的一位管理员提出了一个不寻常的想法&#xff1a;将行李索…...

常用第三方库:shared_preferences数据持久化

常用第三方库&#xff1a;shared_preferences数据持久化 前言 shared_preferences是Flutter中最常用的轻量级数据持久化解决方案&#xff0c;它提供了一个简单的key-value存储机制&#xff0c;适合存储用户配置、应用设置等小型数据。本文将从实战角度深入讲解shared_prefere…...

项目驱动 CAN-bus现场总线基础教程》随笔

阅读&#xff1a;《项目驱动 CAN-bus现场总线基础教程》 仲裁段的实现 有感而发 感觉出人意外之处 感觉出人意外之处 最近在阅读入门的CAN相关书籍时&#xff0c;在介绍仲裁段是如何实现各节点之间&#xff0c;通讯仲裁功能的章节中&#xff0c;有如下一段描述&#xff1a; …...

WPF之XAML基础

文章目录 XAML基础&#xff1a;深入理解WPF和UWP应用开发的核心语言1. XAML简介XAML与XML的关系 2. XAML语法基础元素语法属性语法集合语法附加属性 3. XAML命名空间命名空间映射关系 4. XAML标记扩展静态资源引用数据绑定相对资源引用常见标记扩展对比 5. XAML与代码的关系XAM…...

测试基础笔记第十四天

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、字符串1.字符串2.字符串切片3.查找find&#xff08;&#xff09;4.去除两端空白字符 strip5.字符串转换大小写 lower、upper5.拆分 split()6.字符串的其他常见方…...

Java详解LeetCode 热题 100(01):LeetCode 1. 两数之和(Two Sum)详解

文章目录 1. 题目描述2. 理解题目3. 解法一&#xff1a;暴力枚举法3.1 思路3.2 Java代码实现3.3 代码详解3.4 复杂度分析3.5 适用场景 4. 解法二&#xff1a;哈希表法4.1 思路4.2 Java代码实现4.3 代码详解4.4 复杂度分析4.5 适用场景 5. 解法三&#xff1a;两遍哈希表法5.1 思…...

机器学习之三:归纳学习

正如人们有各种各样的学习方法一样&#xff0c;机器学习也有多种学习方法。若按学习时所用的方法进行分类&#xff0c;则机器学习可分为机械式学习、指导式学习、示例学习、类比学习、解释学习等。这是温斯顿在1977年提出的一种分类方法。 有关机器学习的基本概念&#xff0c;…...

AI声像融合守护幼儿安全——打骂/异常声音报警系统的智慧防护

幼儿园是孩子们快乐成长的摇篮&#xff0c;但打骂、哭闹或尖叫等异常事件可能打破这份宁静&#xff0c;威胁幼儿的身心安全。打骂/异常声音报警系统&#xff0c;依托尖端的AI声像融合技术&#xff0c;结合语音识别、情绪分析与视频行为检测&#xff0c;为幼儿园筑起一道智能安全…...

2024ICPC网络赛第二场题解

文章目录 F. Tourist(签到)I. Strange Binary(思维)J. Stacking of Goods(思维)A. Gambling on Choosing Regionals(签到)G. Game(数学)L. 502 Bad Gateway(数学)E. Escape(BFS)C. Prefix of Suffixes(kmp结论)K. match(01trie分治多项式乘法组合数) 题目链接 F. Tourist(签到…...

风控策略引擎架构设计全解析:构建智能实时决策系统

摘要 本文深入探讨现代风控策略引擎的核心架构设计,结合金融反欺诈、电商交易风控等典型场景,详细解析实时决策、规则引擎、特征计算等关键技术模块的实现方案。通过分层架构设计、分布式计算优化、策略动态编排等创新方法,展示如何构建支撑每秒万级决策的高可用风控系统。…...

TensorFlow 安装全攻略

选择 TensorFlow 的原因&#xff1a; TensorFlow 是一个端到端平台&#xff0c;它提供多个抽象级别&#xff0c;因此您可以根据自己的需求选择合适的级别。您可以使用高阶 Keras API 构建和训练模型&#xff0c;该 API 让您能够轻松地开始使用 TensorFlow 和机器学习。如果您需…...

Dijkstra 算法代码步骤[leetcode.743网络延迟时间]

有 n 个网络节点&#xff0c;标记为 1 到 n。 给你一个列表 times&#xff0c;表示信号经过 有向 边的传递时间。 times[i] (ui, vi, wi)&#xff0c;其中 ui 是源节点&#xff0c;vi 是目标节点&#xff0c; wi 是一个信号从源节点传递到目标节点的时间。 现在&#xff0c;…...

Ubuntu22.04/24.04 P104-100 安装驱动和 CUDA Toolkit

硬件环境 使用一块技嘉 B85m-DS3H 安装 P104-100, CPU是带集成显卡的i5-4690. 先在BIOS中设置好显示设备优先使用集成显卡(IGX). 然后安装P104-100开机. 登入Ubuntu 后查看硬件信息, 检查P104-100是否已经被检测到 # PCI设备 lspci -v | grep -i nvidia lspci | grep NVIDIA …...

Golang 学习指南

目录 变量与常量数据类型与控制结构常用数据结构函数与错误处理指针与并发Gin 框架与 go mod小结与参考资料 1. 变量与常量 变量&#xff08;var&#xff09; 用于定义可变的值。可以指定类型&#xff0c;也可以自动推断类型。示例&#xff1a;var name string "Golang…...

Ubuntu 磁盘空间占用清理(宝塔)

目录 前言1. 基本知识2. 实战 前言 &#x1f91f; 找工作&#xff0c;来万码优才&#xff1a;&#x1f449; #小程序://万码优才/r6rqmzDaXpYkJZF 爬虫神器&#xff0c;无代码爬取&#xff0c;就来&#xff1a;bright.cn 本身自搭建了一个宝塔&#xff0c;突然一下子多了好些空…...

AntBio: 2025 AACR Meeting - Charting New Oncology Frontiers Together

AntBio cordially invites you to attend the 2025 AACR Annual Meeting and jointly chart a new course in oncology research! The global benchmark for cancer research and therapeutics—the 2025 American Association for Cancer Research (AACR) Annual Meeting—wi…...

数模学习:二,MATLAB的基本语法使用

注释代码&#xff1a; (1)在每行语句后面加上分号&#xff0c;则不显示该行代码的运算结果。 在每行代码前加%&#xff0c;则该行代码会被注释掉 (2) 多行注释&#xff1a; 选中要注释的多行语句&#xff0c;按快捷键Ctrl R (3) 取消注释&#xff1a; 选中要注释的多行语句…...

【Webpack \ Vite】多环境配置

环境变量脚本命令 如何通过不同的环境变量或不同的配置文件进行项目区分&#xff0c;动态加载配置。通常&#xff0c;使用环境变量是最简单且灵活的方法&#xff0c;因为它不需要改变构建命令或创建多个配置文件 环境变量 在根目录下创建 .env.xxx 文件&#xff0c;为不同的环…...

已知漏洞打补丁

. 打补丁 根据MS漏洞编号或者CVE漏洞编号都可以找到对应的HotfixID。 1.根据MS漏洞编号可以使用&#xff1a;https://learn.microsoft.com/zh-cn/security-updates/securitybulletins/securitybulletins 即可找到KB编号。 2.根据CVE漏洞编号可以使用&#xff1a;https://cve…...

WGS84(GPS)、火星坐标系(GCJ02)、百度地图(BD09)坐标系转换Java代码

在做基于百度地图、高德地图等电子地图做为地图服务的二次开发时&#xff0c;通常需要将具有WGS84等坐标的矢量数据&#xff08;如行政区划、地名、河流、道路等GIS地理空间数据&#xff09;添加到地图上面。 然而&#xff0c;在线地图大多使用的是火星坐标系&#xff0c;需要…...

R语言操作n

1.加载安装vegan包 2.查看data(varechem)和data(varespec),探索其维度和结构 3.基于varespec构建物种互作网络&#xff0c;输出gml文件并采用gephi可视化为图片&#xff0c;输出pdf&#xff0c;阈值为r>0.6&#xff0c;p<0.05 4.基于varespec和varechem构建物种-环境互作…...

ChatGPT与DeepSeek在科研论文撰写中的整体科研流程与案例解析

随着人工智能技术的快速发展&#xff0c;大语言模型如ChatGPT和DeepSeek在科研领域展现出强大的潜力&#xff0c;尤其是在论文撰写方面。本文旨在介绍如何利用ChatGPT和DeepSeek提升科研论文撰写的效率与质量&#xff0c;并提供一个具体案例&#xff0c;详细阐述其技术流程及公…...

VScode在 Markdown 编辑器中预览

1. 使用在线 Mermaid 编辑器 步骤&#xff1a; 打开 Mermaid Live Editor。将你 .md 文件中的 Mermaid 代码&#xff08;从 mermaid 到结束的代码块&#xff09;复制粘贴到编辑器的左侧输入框。编辑器会自动在右侧生成可视化的 ER 图。你可以点击右上角的下载按钮&#xff0c;…...

驱动开发硬核特训 · Day 22(下篇): # 深入理解 Power-domain 框架:概念、功能与完整代码剖析

一、Power-domain 框架基础概念 ✏️ 什么是 Power-domain&#xff1f; 在 Linux 内核中&#xff0c;Power-domain&#xff08;电源域&#xff09; 是指一组硬件模块的逻辑集合&#xff0c;这些模块可以被统一控制电源状态&#xff08;上电、断电&#xff09;。 Linux 内核通…...

无人机超声波避障技术要点与难点!

一、超声波避障技术要点 4. 障碍物建模 通过最小二乘法平面拟合&#xff0c;将单点测距数据转化为障碍物表面模型&#xff0c;提高避障准确性。 使用队列&#xff08;wallqueue&#xff09;存储障碍物信息&#xff0c;并进行去重处理&#xff0c;避免重复避障。 5. 避障轨…...

ASCII字符编码标准及字符表

目录 概述 1 标准 ASCII 表&#xff08;0-127&#xff09; 2 大写字母&#xff08;A-Z&#xff09; 3 小写字母&#xff08;a-z&#xff09; 4 说明 概述 ASCII&#xff08;American Standard Code for Information Interchange&#xff0c;美国信息交换标准代码&#xff…...

联想昭阳笔记本 风扇一键静音优化操作指南

【联想昭阳笔记本 一键静音优化操作指南】 第1步&#xff1a;安装官方工具 Lenovo Vantage 打开【开始菜单】→ 搜索【Microsoft Store】&#xff0c;打开。在 Store 里搜索【Lenovo Vantage】&#xff0c;下载安装。安装好后&#xff0c;打开【Lenovo Vantage】。进入【设备…...

go语言八股文(三)

1.java和go的区别 1. 语言设计目标 Java&#xff1a; 通用性&#xff1a;设计为一种通用的、面向对象的编程语言&#xff0c;适用于多种应用场景&#xff0c;如桌面应用、服务器端应用、移动应用等。跨平台性&#xff1a;通过“一次编写&#xff0c;到处运行”&#xff08;Wr…...

Flutter 学习之旅 之 flutter 有时候部分手机【TextField】无法唤起【输入法软键盘】的一些简单整理

Flutter 学习之旅 之 flutter 有时候部分手机【TextField】无法唤起【输入法软键盘】的一些简单整理 目录 Flutter 学习之旅 之 flutter 有时候部分手机【TextField】无法唤起【输入法软键盘】的一些简单整理 一、简单介绍 二、现象描述 三、尝试的解决方案 1、根据应用的…...

【工具】scMultiMap基于单细胞多模态数据实现增强子与靶基因的细胞类型特异性映射

文章目录 介绍代码参考 介绍 在与疾病相关的细胞类型中绘制增强子和靶基因图谱&#xff0c;能够为全基因组关联研究&#xff08;GWAS&#xff09;变异的功能机制提供关键见解。单细胞多模态数据能够测量同一细胞中的基因表达和染色质可及性&#xff0c;从而实现细胞类型特异性…...

rt-linux下的cgroup cpu的死锁bug

一、背景 rt-linux系统有其非常大的实时性的优势&#xff0c;但是与之俱来的是该系统上有一些天然的缺陷。由于rt-linux系统允许进程在内核态执行的逻辑里&#xff0c;在持锁期间&#xff0c;甚至持spinlock锁期间&#xff0c;都能被其他进程抢占。这一特性能带来实时性的好处…...

Java 内存泄漏 详解

Java 内存泄漏是指程序中某些对象不再被使用&#xff0c;但由于某些原因无法被垃圾回收器&#xff08;Garbage Collector, GC&#xff09;回收&#xff0c;导致内存被持续占用&#xff0c;最终可能引发性能问题或 OutOfMemoryError。 本文将从底层原理、源码层面详细解释 Java …...

Rabbit MQ的基础认识

零、介绍 MQ&#xff1a;message queue&#xff08;消息队列&#xff1a;先进先出&#xff09; Rabbit MQ&#xff1a; 一、优势 1.应用解耦 2.异步提速 3.削峰填谷 4.总结 二、劣势...

GIS开发笔记(16)解决基于osg和osgearth三维地图上添加placeNode图标点击不易拾取的问题

一、实现效果 二、实现原理 在图标添加的位置同时添加一个红色圆球,半径为5000~8000米,图标和圆球挂接到同一个group节点,group节点再挂接到根节点,当点击到圆球时,通过遍历父节点就可以找到被点击的图标节点。 三、参考代码 //添加图标代码 #pragma once #include &…...

JDBC 使用流程详解

1. 加载数据库驱动 目的&#xff1a;注册数据库驱动类&#xff0c;使 JDBC 能识别特定数据库&#xff08;如 MySQL、Oracle&#xff09;。 代码示例&#xff1a; // JDBC 4.0 后无需显式加载驱动&#xff08;SPI 自动发现&#xff09;&#xff0c;但部分旧项目仍需手动加载 C…...

小白学习java第16天(上): javaWeb

0.背景介绍 1.前言 首先我们需要javaweb里面的大概流程是干什么的&#xff0c;怎么才能实现的&#xff1f;&#xff0c;每一部分是靠什么进行的&#xff1f;以及背后实现的功能是干什么的&#xff1f;。。。。对于我来说要是不解决这些&#xff0c;会让我感觉不踏实&#xff…...

vue 打包设置

1、vue webpack配置 filename: [path][base].gz,// 设置成这样就行了 const { defineConfig } require(vue/cli-service)const debug process.env.NODE_ENV ! productionconst CompressionWebpackPlugin require(compression-webpack-plugin)const TerserPlugin require(…...

Excel如何安装使用EPM插件并且汉化?

Excel如何使用EPM插件 Excel如何使用EPM插件一、安装EPM插件二、启动EPM插件三、插件汉化设置 Excel如何使用EPM插件 一、安装EPM插件 在安装EPM插件时&#xff0c;若运行安装包后出现报错提示&#xff0c;通常是因为系统缺少 Visual Studio 2010 组件&#xff0c;需先安装该…...

在Linux中使用fcntl函数和ioctl函数

特性fcntlioctl作用对象文件描述符&#xff08;通用文件操作&#xff09;设备文件&#xff08;硬件或驱动控制&#xff09;标准化程度POSIX 标准&#xff0c;行为一致设备相关&#xff0c;无统一标准典型场景文件锁、非阻塞模式、描述符复制终端控制、网络配置、硬件操作移植性…...

ESP32-S3 入门学习笔记(四):LED实验

ESP32-S3 入门学习笔记&#xff08;四&#xff09;&#xff1a;LED实验 开发板&#xff1a;正点原子ESP32S3 B站学习链接&#xff1a;link 1. GPIO&LED 简介 1.1 GPIO 简介 GPIO 是负责控制或采集外部器件信息的外设&#xff0c;主要负责输入输出功能。以下是ATK-MWS3S…...

clickhouse#复制修改数据

需求 在ClickHouse表中存在一些数据&#xff0c;你需要复制其中几行数据&#xff0c;这个复制不是完全复制&#xff0c;额外需要修改其中某几列数据项。 语句 INSERT INTO xxx_table SELECT * REPLACE ({except_value_1} AS {column_name_1},...{except_value_n} AS {colum…...