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

Selenium学习(Java + Edge)

Selenium

/səˈliːniəm/

1. 简介

​ Selenium是一个用于Web应用程序自动化测试工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE、Mozilla Firefox、Safari、Google Chrome、Opera、Edge等。

​ 适用于自动化测试,js动态爬虫(破解反爬虫)等领域。

​ Selenium的核心Selenium Core基于JsUnit,完全由JavaScript编写,因此可以用于任何支持JavaScript的浏览器上。selenium可以模拟真实浏览器,自动化测试工具,支持多种浏览器。

Selenium官方

2. 组成

  • Selenium IDE:嵌入到Firefox浏览器中的一个插件,实现简单的浏览器操作录制与回放功能,主要用于快速创建BUG及重现脚本,可转化为多种语言;
  • Selenium RC: 核心组件,支持多种不同语言编写自动化测试脚本,通过其服务器作为代理服务器去访问应用,达到测试的目的;
  • Selenium WebDriver(重点):一个浏览器自动化框架,它接受命令并将它们发送到浏览器。它是通过特定于浏览器的驱动程序实现的。它直接与浏览器通信并对其进行控制。Selenium WebDriver支持各种编程语言,如Java、C# 、PHP、Python、Perl、Ruby;
  • Selenium grid:测试辅助工具,用于做分布式测试,可以并行执行多个测试任务,提升测试效率。

3. 特点

  1. 开源、免费
  2. 多浏览器支持:FireFox、Chrome、IE、Opera、Edge;
  3. 多平台支持:Linux、Windows、MAC;
  4. 多语言支持:Java、Python、Ruby、C#、JavaScript、C++;
  5. 对Web页面有良好的支持;
  6. 简单(API 简单)、灵活(用开发语言驱动);
  7. 支持分布式测试用例执行。

4. 配置

采用Java编写自动化测试代码。

4.1 环境依赖

注意:浏览器版本必须与Selenium驱动版本一致!

Edge:118.0.2088.76 x64

Selenium驱动:118.0.2088.76

Maven依赖:4.8.0

JDK:1.8.0_361

4.2 下载对应浏览器的驱动

注意:下载的驱动包需要与当前浏览器版本对对应。

4.4 配置驱动包

​ 将驱动包解压到jdk / bin目录下。

5. 运行

5.1 创建Maven项目

在这里入图片描述
在这里插入图片描述

5.2 导入Selenium依赖

pom.xml

<dependencies><dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>4.8.0</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version></dependency>
</dependencies>

5.3 在test /java下创建类

在这里插入图片描述

或者直接在src -> main -> java下新建。

5.4 在自动化测试类中编写代码

// 自动化测试类
public class AutoTest  {public void Test() throws InterruptedException, IOException {// Edge驱动EdgeOptions edgeOptions = new EdgeOptions();// 允许所有请求(允许浏览器通过远程服务器访问不同源的网页,即跨域访问)edgeOptions.addArguments("--remote-allow-origins=*");EdgeDriver edgeDriver = new EdgeDriver(edgeOptions);// 启动需要打开的网页edgeDriver.get("https://www.baidu.com");// 退出edgeDriver.quit();}
}
import java.io.IOException;// 启动类
public class RunAutoTest {public static void main(String[] args) throws InterruptedException, IOException {AutoTest autoTest = new AutoTest();autoTest.Test();}
}

5.5 启动

6. 使用

6.1 请求

方法说明
driver.get(url)请求一个页面,不支持前进和后退切换
driver.navigate().to(url)和get类似,支持前进和后退切换
driver.navigate().forward(url)指前进到下一个页面(必须后退一个页面后才能前进)
driver.navigate().back(url)退到上一个页面(必须前进了一个页面才能回退)
driver.navigate().refresh(url)刷新当前页面

6.2 定位元素

方法描述
driver.findElement(By.id())使用元素的唯一标识ID进行定位
driver.findElement(By.name())使用元素的名称属性进行定位
driver.findElement(By.className())使用元素的类名进行定位
driver.findElement(By.tagName)使用元素的标签名进行定位
driver.findElement(By.partialLinkText())使用链接文本进行定位
driver.findElement(By.cssSelector)使用CSS选择器进行定位
driver.findElement(By.xpath)使用XPath表达式进行定位

cssSelector:

在这里插入图片描述

cv工程


元素定位—cssSelector

  1. 根据tagName

    By.cssSelector("input");// 不推荐,tagName会重复
    
  2. 根据ID

    By.cssSelector("input#id");
    By.cssSelector("#id");
    
  3. 根据className(样式名)

    By.cssSelector(".className");
    By.cssSelector("input.className");
    

css精确定位

  1. 根据元素属性,属性名=属性值(id、calss等都可使用此形式)

    // By.cssSelector("标签名[属性名='属性值']");
    By.cssSelector("input[name='xxx']");
    
  2. 多属性

    By.cssSelector("标签名[属性名='属性值'][属性名='属性值']");
    

6.3 获取内容

方法说明
String getPageSource()获取页面html
String getTitle()获取页面标题
String getText()获取此元素(包括子元素)的可见(即未被CSS隐藏)文本
String getTagName()获取此元素的标签名
String getAttribute(String name)获取元素指定属性的值
Point getLocation()获取当前元素,基于页面左上角的为准
Dimension getSize()渲染元素的宽度和高度是多少
String getCurrentUrl()获取表示浏览器正在查看的当前URL的字符串
String getCssValue(String propertyName)获取指定元素的CSS属性的值

6.4 操作行为

方法说明
clear()如果该元素是文本输入元素,则会清除该值
submit()提交from表单
click()单击此元素
sendKeys()使用此方法模拟在元素中键入,可以设置其值

注意:

有些页面是使用动态加载js的,会导致html页面正常显示,但js还没执行完毕,相关事件还没绑定到具体的元素上。导致出现操作无效或程序抛出异常。

可以在加载页面时强制等待,全部加载完毕后再进行后续操作。

6.5 窗口

方法说明
driver.manage().window().setSize(new Dimension(1024, 768))设置当前窗口的大小
driver.manage().window().setPosition()设置当前窗口的位置(相对于屏幕的左上角)
driver.manage().window().getSize()获取当前窗口的大小
driver.manage().window().getPosition()获取当前窗口相对于屏幕左上角的位置
driver.manage().window().fullScreen()全屏当前窗口
driver.manage().window().maximize()最大化当前窗口

6.6 切换指定窗口

​ 当浏览器每次打开一个标签页的时候,会自动的给一个标签进行标识,这个标识我们称之为“句柄”。

方法说明
String getWindowHandle()返回当前窗口句柄,通过将其传递给switchTo(),进行切换窗口
driver.switchTo().window(windowHandle)切换到指定句柄的窗口
    String curHandle = edgeDriver.getWindowHandle();// 获取当前页面句柄System.out.println("当前句柄:" + curHandle);Set<String> handles = edgeDriver.getWindowHandles();// 获取所有页面句柄for (String handle : handles) {if (!handle.equals(curHandle)) {// 发生页面切换edgeDriver.switchTo().window(handle);// 切换窗口}}

6.7 iframe切换

方法说明
driver.switchTo().frame(index)根据index进行切换
driver.switchTo().frame(id)根据id进行切换
driver.switchTo().frame(name)根据name进行切换
driver.switchTo().frame(WebElement)根据WebElement进行切换
driver.switchTo().defaultContent()切换后,回到默认内容页面(否则会找不到元素)

6.8 模拟键盘和鼠标

6.8.1 键盘事件
方法说明
driver.findElement(By.id(“kw”)).sendKeys(Keys.CONTROL, “a”)ctrl+a
driver.findElement(By.id(“kw”)).sendKeys(Keys.CONTROL, “c”)ctrl+c
driver.findElement(By.id(“kw”)).sendKeys(Keys.CONTROL, “v”)ctrl+v
driver.findElement(By.id(“kw”)).sendKeys(Keys.TAB)TAB键
driver.findElement(By.id(“kw”)).sendKeys(Keys.ENTER)回车键
driver.findElement(By.id(“kw”)).sendKeys(Keys.SPACE)空格键
6.8.2 鼠标事件
Actions actions = new Actions(driver);
方法说明
actions.contextClick(element).perform()右键点击enement的元素
actions.clickAndHold(element).perform()左键单击enement元素
actions.doubleClick(element).perform()鼠标左键双击enement元素
actions.moveToElement(element).perform()鼠标悬停enement元素(中间)
actions.moveToElement(element,x,y).perform()鼠标悬停enement元素(指定位置)
actions.moveToElement(x,y).perform();将鼠标从其当前位置移动鼠标
Actions dragAndDrop(WebElement source, WebElement target)拖动元素, 在源元素的位置执行点击并保持,移动到目标元素的位置,然后释放鼠标
Actions dragAndDropBy(WebElement source, int xOffset, int yOffset) 拖动到指定位置拖动到指定位置

6.9 等待

6.9.1 强制等待
    Thread.sleep(millisecond);

程序阻塞执行,不建议。

6.9.2 显式等待

​ 显式等待是添加到代码中的循环,在应用程序退出循环并继续执行代码中的下一个命令之前,它会轮询应用程序以查找特定条件以评估为true。如果在指定的超时值之前未满足条件,则代码将给出超时错误。

WebElement revealed = driver.findElement(By.id("revealed"));
Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(2));driver.findElement(By.id("reveal")).click();
wait.until(d -> revealed.isDisplayed());revealed.sendKeys("Displayed");
6.9.3 隐式等待

​ 这是一个全局设置,适用于整个会话的每个元素位置调用。默认值为0,这意味着如果找不到元素,它将立即返回错误。如果设置了隐式等待,则在返回错误之前,驱动程序将等待所提供值的持续时间。请注意,一旦找到元素,驱动程序将返回元素引用,代码将继续执行,因此较大的隐式等待值不一定会增加会话的持续时间。

driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));

注意:

​ 不要混合隐式和显式等待。这样做可能会导致不可预测的等待时间。

​ 例如,设置10秒的隐式等待和15秒的显式等待可能会导致20秒后发生超时。

6.10 弹窗

  1. 警告弹窗中, 切换到弹窗,调用 accept()
  2. 确认弹窗中, 切换到弹窗,调用 accept() 或者 dismiss()
  3. 提示弹窗中, 切换到弹窗, 可以先输入文本, 调用 sendKeys(), 然后调用 accept() 或者 dismiss().
    提示:这里的 sendKeys() 在页面上看不到输入文本的执行效果
driver.get("...");
Thread.sleep(3000);// 打开弹窗
driver.findElement(By.cssSelector("body > input[type=button]")).click();
Thread.sleep(3000);// 切换到弹窗进行弹窗的处理
Alert alert = driver.switchTo().alert();
Thread.sleep(3000);// 弹窗输入文本
alert.sendKeys("abcdef");// 点击确认
alert.accept();// 点击取消
// alert.dismiss();driver.quit();
6.10.1 警告弹窗

警告弹窗中, 切换到弹窗,调用 accept()

6.10.2 确认弹窗

确认弹窗中, 切换到弹窗,调用 accept() 或者 dismiss()

6.10.3 提示弹窗

提示弹窗中, 切换到弹窗, 可以先输入文本, 调用 sendKeys(), 然后调用 accept() 或者 dismiss().
提示:这里的 sendKeys() 在页面上看不到输入文本的执行效果

6.11 下拉选择框

方法说明
select.getOptions()获取所有选项
select.selectByIndex(index)根据索引选中对应的元素
select.selectByValue(value)选择指定value值对应的选项
select.selectByVisibleText(text)选中文本值对应的选项
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body>
<select name="ss" id="sss"><option value="12.5">**12.5**</option><option value="6.6">**6.6**</option><option value="486.4">**486.4**</option><option value="21.12">**21.12**</option><option value="99.99">**99.99**</option>
</select>
</body>
</html>
package org.example;import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.support.ui.Select;import java.time.Duration;public class Main {public static void main(String[] args) throws Exception {EdgeOptions edgeOptions = new EdgeOptions();edgeOptions.addArguments("--remote-allow-origins=*");EdgeDriver edgeDriver = new EdgeDriver(edgeOptions);edgeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));// 隐式等待edgeDriver.get("file:///D:/idea-workspace/WebTest/src/main/resources/web/fileUpload/select.html");//        WebElement webElement = edgeDriver.findElement(By.cssSelector("sss"));
//        Select select = new Select(webElement);Select select = new Select(edgeDriver.findElement(By.cssSelector("#sss")));// 根据文本选择Thread.sleep(3000);select.selectByVisibleText("**99.99**");// 根据索引值选择Thread.sleep(3000);select.selectByIndex(1);// 根据属性值选择Thread.sleep(3000);select.selectByValue("6.6");Thread.sleep(1000);edgeDriver.quit();}
}
6.11.1 根据文本选择
WebElement webElement = driver.findElement(By.cssSelector("#Method"));// 创建选择框对象(将此web元素封装为Select对象)
Select select = new Select(webElement)// 根据文本来选择
select.selectByVisibleText("选择框文本");Thread.sleep(3000);
driver.quit();
6.11.2 根据属性值选择
WebElement webElement = driver.findElement(By.cssSelector("#Method"));// 创建选择框对象(将此web元素封装为Select对象)
Select select = new Select(webElement)// 根据属性值来选择
select.selectByValue("选择框属性值");Thread.sleep(3000);
driver.quit();
6.11.3 根据序号选择

注意:select下拉框索引值从0开始!

WebElement webElement = driver.findElement(By.cssSelector("#Method"));// 创建选择框对象(将此web元素封装为Select对象)
Select select = new Select(webElement)// 根据序号来选择
select.selectByIndex(1);Thread.sleep(3000);
driver.quit();

6.12 文件上传

public void fileUploadController() throws InterruptedException {driver.get("");Thread.sleep(3000);driver.findElement(By.cssSelector("body > div > div > input[type=file]")).sendKeys("文件路径");Thread.sleep(3000);driver.quit();
}

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body>
<input type="file" id="fu" value="选择文件">
<br>
<input type="button" id="fw" value="上传">
</body>
</html>

package org.example;import org.openqa.selenium.By;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;import java.time.Duration;public class Main {public static void main(String[] args) throws InterruptedException {System.out.println("Hello world!");EdgeOptions edgeOptions = new EdgeOptions();edgeOptions.addArguments("--remote-allow-origins=*");EdgeDriver edgeDriver = new EdgeDriver(edgeOptions);edgeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));// 隐式等待edgeDriver.get("file:///D:/idea-workspace/WebTest/src/main/resources/web/fileUpload/fileUpload.html");Thread.sleep(3000);edgeDriver.findElement(By.cssSelector("#fu")).sendKeys("D:/idea-workspace/WebTest/src/main/resources/web/fileUpload/fileUpload.html");Thread.sleep(3000);edgeDriver.quit();}
}

在这里插入图片描述
在这里插入图片描述

注意:如果上传文件前端控件源码不是input类型,需要使用第三方工具,比如:autoit

6.13 时间日期控件

  • 控件没有限制手动输入,则直接调用sendKeys方法写入时间数据。
  • 控件有限制输入,则可以通过执行一段js脚本来改变元素的value属性值。
6.13.1 方式一
package org.example;import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.support.ui.Select;import java.time.Duration;public class Main {public static void main(String[] args) throws InterruptedException {EdgeOptions edgeOptions = new EdgeOptions();edgeOptions.addArguments("--remote-allow-origins=*");EdgeDriver edgeDriver = new EdgeDriver(edgeOptions);edgeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));// 隐式等待edgeDriver.get("https://www.fliggy.com/?ttid=seo.000000580&seoType=origin");edgeDriver.findElement(By.cssSelector("#J_FlightForm > fieldset > div:nth-child(5) > div > div > input")).sendKeys("2000-01-01");Thread.sleep(1000);edgeDriver.quit();}
}
6.13.2 方式二
	见 6.13 执行脚本

6.13 执行脚本

方法说明
driver.executeScript()参数为要执行的js脚本
package org.example;import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.support.ui.Select;import java.time.Duration;public class Main {public static void main(String[] args) throws InterruptedException {EdgeOptions edgeOptions = new EdgeOptions();edgeOptions.addArguments("--remote-allow-origins=*");EdgeDriver edgeDriver = new EdgeDriver(edgeOptions);edgeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));// 隐式等待edgeDriver.get("https://www.12306.cn/index/");
//        edgeDriver.findElement(By.id("train_date"));
//        edgeDriver.executeScript("var v = train_date;\n" + "v.autocomplete = true");edgeDriver.executeScript("var v = train_date; v.autocomplete = true");edgeDriver.findElement(By.id("train_date")).clear();edgeDriver.findElement(By.id("train_date")).sendKeys("2000-01-01");Thread.sleep(1000);edgeDriver.quit();}
}

在这里插入图片描述

在这里插入图片描述

6.14 浏览器参数设置

EdgeOptions edgeOptions = new EdgeOptions();
edgeOptions.addArguments("--remote-allow-origins=*");
addArguments可接收参数说明
“–disable-gpu”禁用GPU加速
“–headless”在无头模式下运行浏览器,即不显示图形界面
“–incognito”在隐身模式下启动浏览器
“–disable-extensions”禁用浏览器扩展
“–disable-notifications”禁用浏览器通知
“–disable-popup-blocking”禁用弹出窗口拦截功能
“–start-maximized”启动时最大化浏览器
“–disable-infobars”禁用信息栏(例如Chrome正在受到自动测试软件控制)
“–ignore-certificate-errors”忽略证书错误
“–proxy-server=http://hostname:port”设置代理服务器

注意:浏览器的参数设置需要在创建浏览器对象之前进行设置。

6.15 验证码

6.15.1 万能验证码(推荐)

​ 后端代码添加测试通用验证码。

6.15.2 去除验证码

​ 后端去除验证码。

6.15.3 自动识别(难度大)

​ 可以付费调用自动识别API,不推荐。

6.16 退出

方法说明
driver.close()关闭当前窗口(如果是当前打开的最后一个窗口,则退出浏览器)
driver.quit()退出此驱动程序,关闭每个相关窗口

在操作完毕后必须调用quit()进行释放资源,否则驱动将持续在内存中不会被释放掉。

7. 最后

码字不易,xdm,qiuqiu点个👍吧!
在这里插入图片描述

相关文章:

Selenium学习(Java + Edge)

Selenium /səˈliːniəm/ 1. 简介 ​ Selenium是一个用于Web应用程序自动化测试工具。Selenium测试直接运行在浏览器中&#xff0c;就像真正的用户在操作一样。支持的浏览器包括IE、Mozilla Firefox、Safari、Google Chrome、Opera、Edge等。 ​ 适用于自动化测试&#x…...

项目管理-组织战略类型和层次讲解

组织战略类型和层次 对于不同的组织战略可能会采用不同的项目管理形式&#xff0c;组织作为项目管理的载体&#xff0c;其战略决策对项目管理体系的架构&#xff0c;对组织与项目之间责权利的划分具有深远的影响&#xff0c;组织的战略文化也会影响到项目的组织文化氛围。因此…...

面试算法50:向下的路径节点值之和

题目 给定一棵二叉树和一个值sum&#xff0c;求二叉树中节点值之和等于sum的路径的数目。路径的定义为二叉树中顺着指向子节点的指针向下移动所经过的节点&#xff0c;但不一定从根节点开始&#xff0c;也不一定到叶节点结束。例如&#xff0c;在如图8.5所示中的二叉树中有两条…...

dbeaver查看表,解决证书报错current license is non-compliant for [jdbc]

http://localhost:9200/_license { “license” : { “status” : “active”, “uid” : “b91ae0e0-b04d-4e20-8730-cf0bca7b2035”, “type” : “basic”, “issue_date” : “2023-02-22T14:33:27.648Z”, “issue_date_in_millis” : 1677076407648, “max_nodes” : 10…...

网络安全进阶学习第二十一课——XXE

文章目录 一、XXE简介二、XXE原理三、XXE危害四、XXE如何寻找五、XXE限制条件六、XXE分类七、XXE利用1、读取任意文件1.1、有回显1.2、没有回显 2、命令执行&#xff08;情况相对较少见&#xff09;3、内网探测/SSRF4、拒绝服务攻击(DDoS)4.1、内部实体4.2、参数实体 八、绕过基…...

如何将 ruby 打包类似于jdk在另一台相同架构的机器上面开箱即用

需求 目前工作中使用到了ruby作为java 项目的中转语言&#xff0c;但是部署ruby的时候由于环境的不同会出现安装依赖包失败的问题&#xff0c;如何找到一种开箱即用的方式类似于java 中的jdk内置jvm这种方式 解决 TruffleRuby 完美解决问题&#xff0c;TruffleRuby 是使用 T…...

vue封装独立组件:实现分格密码输入框/验证码输入框

目录 第一章 实现效果 第二章 核心实现思路 第三章 封装组件代码实现 第一章 实现效果 为了方便小编的父组件随便找了个页面演示的通过点击按钮&#xff0c;展示子组件密码输入的输入框通过点击子组件输入框获取焦点&#xff0c;然后输入验证码数字即可子组件的确定按钮是验…...

从2D圆形到3D椭圆

要将一个2D圆形转换成3D椭圆&#xff0c;我们需要使用CSS的transform属性和一些基本的几何知识。首先&#xff0c;让我们创建一个HTML元素&#xff0c;如下所 html <div class"circle"></div> 然后&#xff0c;使用CSS样式将其转换成3D椭圆 css .circ…...

Linux CentOS7.9安装OpenJDK17

Linux CentOS7.9安装OpenJDK17 一、OpenJDK下载 清华大学开源软件镜像站 国内的站点&#xff0c;下载速度贼快 二、上传解压 文件上传到服务器后&#xff0c;解压命令&#xff1a; tar -zxvf jdk-xxxx-linux-x64.tar.gz三、配置环境 export JAVA_HOME/home/local/java/j…...

计算机网络第4章-网络层(1)

引子 网络层能够被分解为两个相互作用的部分&#xff1a; 数据平面和控制平面。 网络层概述 路由器具有截断的协议栈&#xff0c;即没有网络层以上的部分。 如下图所示&#xff0c;是一个简单网络&#xff1a; 转发和路由选择&#xff1a;数据平面和控制平面 网络层的作用…...

单元测试学习

回顾测试理论基础 单元测试基础知识 什么是单元测试 单元测试流程、测试计划 测试策略设计、实现 单元测试 - 执行 HTML 报告生成 1 软件测试分类 目标 回顾测试理论知识-测试分类 1. 测 试分类 代码可见度上-划分分类&#xff1a; 1. 黑盒测试 2. 灰盒测试 3. …...

python编写接口测试文档(以豆瓣搜索为例)

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…...

C++查看Class类结构

cl指令 cl test.cpp /d1reportSingleClassLayout 类名 注意。上面指令是d1,1是数字1 &#xff0c; 不是字母l;...

appium如何连接多台设备

我们在做app自动化的时候&#xff0c;若要考虑兼容性问题&#xff0c;需要跑几台设备&#xff0c;要是一台一台的跑比较耗时&#xff0c;因此需要考虑使用多线程来同时操作多台设备。 1.我们拿两台设备来模拟操作下&#xff0c;使用&#xff1a;adb devices查看连接状况&#…...

VUE el-form组件不绑定model时进行校验

在el-form中如果要使用:rules规则校验时,需要在el-form标签绑定 :model 如何不绑定model而进行校验字段: 思路: 1.假设规则为非空判断 2.获取该字段,进行非空判断,记录该字段是否校验完成,添加到校验标识中 3.表单或数据提交时,判断校验标识 required 红星星 :error 提示项 …...

计算机视觉的监督学习与无监督学习

什么是监督学习&#xff1f; 监督学习是一种机器学习算法&#xff0c;它从一组已标记的 合成数据生成器中生成的训练数据中学习。这意味着数据科学家已经用正确的标签&#xff08;例如&#xff0c;“猫”或“狗”&#xff09;标记了训练集中的每个数据点&#xff0c;以便算法可…...

Linux-lvds接口

lvds接口 单6 单8 双6 双8...

Android 自定义View一

1.继承已有VIew&#xff0c;改写尺寸&#xff1a;重写onMeasure SquareImageView 2.完全自定义重写onMeasure 3.自定义Layout 重写onMeasure onLayout 1.继承已有VIew&#xff0c;改写尺寸&#xff1a;重写onMeasure 流程&#xff1a; 重写onMeasure 用getmeasureedWidth …...

11、电路综合-集总参数电路结构的S参数模型计算与Matlab

11、电路综合-集总参数电路结构的S参数模型 电路综合专栏的大纲如下&#xff1a; 网络综合和简化实频理论学习概述 前面介绍了许多微带线电路综合的实际案例&#xff0c;如&#xff1a; 3、电路综合原理与实践—单双端口理想微带线&#xff08;伪&#xff09;手算S参数与时域…...

计算机网络--真题

因特网上专门用于传输文件的协议是 因特网上专门用于传输文件的协议通常是 FTP&#xff08;File Transfer Protocol&#xff09;。FTP 是一种标准的网络协议&#xff0c;用于在计算机之间传输文件。它允许用户在客户端和服务器之间传输文件&#xff0c;上传文件到服务器或从服务…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...