自动化测试—Selenium(Java)

自动化测试—Selenium(Java)

一.引入selenium依赖

 <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>4.0.0</version> </dependency>

二.下载浏览器驱动

方法一:手动下载

Unable to Locate Driver Error | Seleniumhttps://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location/通过该链接就能直接进入Selenium官网下载不同浏览器的驱动

注意选择下载的浏览器驱动要与自己的浏览器版本相近

比如自己的浏览器版本为144.0.3719.82

那么在下载浏览器驱动里就要选择144.0.3719.82

如果没有对应一模一样的话,选相近版本的即可

下载完,创建一个专门保管浏览器驱动的文件夹并保存在里面

如D:\drivers\edgedriver_win64

然后在Java方法中使用如下代码,即可创建浏览器驱动

System.setProperty("webdriver.edge.driver", "D:\\drivers\\edgedriver_win64\\msedgedriver.exe");

其中前面的"webdriver.***.driver"中,***可以选择对应的浏览器名字,比如是edge的就用edge,是chrome的就用chrome,后面就是浏览器驱动下载的文件路径

方法二:驱动管理

不过方法一也有缺陷,那就是不同的浏览器就要下载对应的驱动,假如有四种不同的浏览器要使用,那么就要手动下载四个对应的浏览器驱动,很麻烦。同时,因为浏览器会有版本更新,一旦更新,就有可能使得我们之前下载的浏览器驱动过时,无法使用,这是手动下载的缺陷。

所以我们就有更方便的方法,那就是驱动管理,它能够自动下载我们电脑里浏览器对应版本的驱动

1.引入驱动管理依赖

 <dependency> <groupId>io.github.bonigarcia</groupId> <artifactId>webdrivermanager</artifactId> <version>5.8.0</version> </dependency> 

2.

使用以下代码即可自动下载好浏览器驱动

WebDriverManager.edgedriver().setup();

需要选择我们要的浏览器的驱动,然后在setup()即可

不过缺点是这个很吃网络,很容易无法使用

三.添加配置

 //添加配置:允许访问所有的连接 EdgeOptions options=new EdgeOptions(); options.addArguments("--remote-allow-origins=*");

先创建对应浏览器的配置器,edge的就要EdgeOptions,chrome就用ChromeOptions

然后下一句是通用的,代表允许访问所有的连接

四.打开浏览器

WebDriver driver=new EdgeDriver(options);

同样的,如果是edge就创建EdgeDriver,是chrome就创建ChromeDriver

此后,所有的自动化都是靠这个driver来操作

其中selenium+驱动+浏览器的工作原理,是通过selenium编写自动化脚本代码,然后运行该代码会发送给驱动,驱动就会根据这些请求去操控浏览器,最后浏览器执行完返回给驱动,驱动再将结果返回给脚本,实现自动化

五.自动化测试常用函数

1.打开网址

driver.get()

driver.get("https://www.bilibili.com/");

2.定位web页面元素

查找一个元素:driver.findElement()

而查找web页面元素有两种方式,选择器和xpath

第一种:cssSelector(选择器)

打开F12开发者工具

其中点击左上角的选择元素

将鼠标对准要选择的页面元素并点击

右侧就会自动锁定对应元素位置,再右键点击该行代码,里面会有复制选项

选择selector就是选择器的路径

body > p:nth-child(54)

再粘贴出来就是该元素的选择器路径

第二种:xpath

步骤与上述一样,只是最后复制中,选择复制xpath即可(选择复制XPath即可,不用选择复制完整的XPath)

/html/body/p[40]

而选择器语法跟前端选择器语法差不多,就是通过id选择器和子类选择器去定位,然后找子元素等等,简单能看懂即可

而xpath语法跟常见路径语法差不多,//*代表获取当前页面的全部节点,/是子节点,..是父节点,需要注意的是xpath的索引是从1开始的,而不是0

findElement()是查找一个元素,如果是要查找多个元素,那么就要使用findElements(),其返回值类型为List<WebElement>

3.操作测试对象

定位到元素后,就是对元素进行操作

点击元素:click()

 //找到“百度一下”按钮并点击 driver.findElement(By.xpath("//*[@id=\"su\"]")).click();

模拟按键输入:sendKeys("")

 //找到输入框并输入“迪丽热巴” driver.findElement(By.xpath("//*[@id=\"kw\"]")).sendKeys("迪丽热巴");

清除文本内容:clear()

 //清除输入框 driver.findElement(By.xpath("//*[@id=\"kw\"]")).clear();

获取文本信息:getText()

 //获取文本信息 driver.findElement(By.xpath("//*[@id=\"kw\"]")).getText();

网页上有些文字不是文本,而是属性值,因此使用getText不能获取的文本信息,而要使用getAttribute("value")

获取当前页面标题:getTitle()

driver.getTitle(); 

获取当前页面的URL:getCurrentUrl()

driver.getCurrentUrl();

4.窗口

经过一些元素操作,可能会新增窗口,但是在代码中,并不会自动切换到新窗口,而是停留在旧窗口,因此需要切换句柄来实现选择控制哪一个页面

获取当前页面的句柄:getWindowHandle(),其返回值类型是String

获取所有页面的句柄:getWindowHandles(),其返回值类型是Set<String>

切换句柄:switchTo().window(句柄)

窗口最大化:manage().window().maximize()

窗口最小化:manage().window().minimize()

全屏窗口:manage().window().fullscreen()

手动设置窗口大小:manage().window().setSize(new Dimension(长,宽))

屏幕截图:

需要引入依赖

 <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency>

代码

 //将当前页面截图 File srcfile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE); //把srcfile转成图片文件 FileUtils.copyFile(srcfile,new File("test.png"));

关闭窗口:driver.close();

注意,关闭之后,driver需要重新指定

5.等待

通常代码执行速度比页面渲染速度要快,所以经常会发生代码执行到了,但当前页面还在加载的情况,所以需要让代码等待页面加载完再操作

一共有三种等待方法:强制等待、隐式等待、显示等待

强制等待:Thread.sleep()

直接指定要求等待多少秒,简单有效,但影响运行效率

隐式等待:implicitlyWait()

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

其中Duration里面有各种时间规格,包括毫秒、秒、分钟等

隐式等待就是在指定时间内不断查找该元素,如果找到了就继续执行,超时没找到才会报错

而且指定一次,就一直作用于所有元素,且一直生效,直到driver被释放

显示等待:

WebDriverWait wait = new WebDriverWait(driver,Duration.ofSeconds(10));

跟隐式等待一样,也是设置超时时间,但隐式等待主要用于查找元素,而显示等待可以设置自定义等待条件

wait.until(ExpectedConditions.***)

里面有各种各样的条件,当在超时时间内符合条件,就继续往后执行

注意:不要将隐式等待和显示等待混合,最后结果是无法预测的等待时间

6.浏览器导航

浏览器前进:forward()

driver.navigate().forward();

浏览器后退:back()

driver.navigate().back();

浏览器刷新:refresh()

driver.navigate().refresh();

7.弹窗

如果蹦出弹窗,那么就无法操作弹窗后面的页面元素,此时就需要对弹窗进行操作

还是先切换句柄到弹窗上:

Alert alert=driver.switchTo.alert();

然后弹窗一般都有确认和取消两个按键

选择确认:

alert.accept();

选择取消:

alert.dismiss();

如果是弹窗里需要输入内容:

alert.sendKeys("hello");

8.文件上传

一般点击文件上传按钮会弹出弹窗

但是这个弹窗是不能被操作的

所以文件上传的方式不是点击选择文件这个按钮,而是通过定位该按键的位置,再用sendKeys方法上传文件路径

driver.findElement(By.cssSelector("body > div > div > input[type=file]")).sendKeys("D:\\file\\比特教务\\测试\\测试课件\\test.txt");

8.浏览器参数设置

无头模式:

无头模式就是后台运行的意思,默认是有头模式,即执行自动化脚本时,会在屏幕上展示自动化的各种操作,而无头模式就不会展示,只有关注终端结果即可

//添加无头模式 options.addArguments("-headless");

浏览器加载策略:

默认的浏览器加载策略是等全部页面元素加载完再执行自动化脚本,而有时候页面元素过多,需要加载很久,这时候效率就比较慢。

所以如果当页面中主要框架加载出来就可以继续执行后面的自动化脚本的话,就可以提高效率

有三个加载策略:

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

其中none策略是完全不阻塞webdriver

eager策略是DOM访问准备就绪即可

normal策略就是默认值,等待所有的资源下载完成

因此none效率最高,其次是eager,最后才是normal

Read more

【C++】哈希表模拟:闭散列技术与哈希冲突处理

【C++】哈希表模拟:闭散列技术与哈希冲突处理

C++语法相关知识点可以通过点击以下链接进行学习一起加油!命名空间缺省参数与函数重载C++相关特性类和对象-上篇类和对象-中篇类和对象-下篇日期类C/C++内存管理模板初阶String使用String模拟实现Vector使用及其模拟实现List使用及其模拟实现容器适配器Stack与QueuePriority Queue与仿函数模板进阶-模板特化面向对象三大特性-继承机制面向对象三大特性-多态机制STL 树形结构容器二叉搜索树AVL树红黑树红黑树封装map/set哈希-开篇 在上一篇《哈希之路:序篇的知识启航》中,我们简要介绍了哈希方法及哈希表的基础概念。本篇将进一步探讨如何利用闭散列技术有效解决哈希冲突,并通过模拟实现哈希表的过程,深入解析这一关键技术。 🌈个人主页:是店小二呀 🌈C语言专栏:C语言 🌈C++专栏: C++ 🌈初阶数据结构专栏: 初阶数据结构 🌈高阶数据结构专栏: 高阶数据结构 🌈Linux专栏: Linux 🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅 文章目录 * 前文 * 一、闭散列 * 1.1 线性探测

By Ne0inhk
【优选算法必刷100题】第025~26题(前缀和算法):【模版】前缀和、【模板】二维前缀和

【优选算法必刷100题】第025~26题(前缀和算法):【模版】前缀和、【模板】二维前缀和

🔥艾莉丝努力练剑:个人主页 ❄专栏传送门:《C语言》、《数据结构与算法》、C/C++干货分享&学习过程记录、Linux操作系统编程详解、笔试/面试常见算法:从基础到进阶 ⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平 🎬艾莉丝的简介: 🎬艾莉丝的算法专栏简介: 目录 025  【模板】一维前缀和 1.1  算法思路:前缀和 1.2  算法实现 1.2.1  C++实现 1.2.2  Java实现 1.3  博主手记 026  【模板】二维前缀和 2.1  算法思路:前缀和

By Ne0inhk
极致高效的数据处理:位图、布隆过滤器与哈希切分的奇妙之旅

极致高效的数据处理:位图、布隆过滤器与哈希切分的奇妙之旅

文章目录 * 前言 * 📮一、位图 * 📧1.1 面试题 * 📧1.2 位图的概念 * 📧1.3 位图的解决方案 * 📩1.3.1 原理 * 📩1.3.2 实现步骤 * 📩1.3.3 实现过程 * 📩1.3.4 优点 * 📧1.4 位图应用 * 📮二、布隆过滤器 * 📧2.1 布隆过滤器的开发历史 * 📧2.2 什么是布隆过滤器 * 📧2.3 布隆过滤器的实现原理 * 📩2.3.1 布隆过滤器的初步认识 * 📩2.3.2

By Ne0inhk
【LeetCode_27】移除元素

【LeetCode_27】移除元素

刷爆LeetCode系列 * LeetCode27题: * github地址 * 前言 * 题目描述 * 题目思路分析 * 代码实现 * 算法代码优化 LeetCode27题: github地址 有梦想的电信狗 前言 本文用C++实现LeetCode 第27题 题目描述 题目链接:https://leetcode.cn/problems/remove-element/ 题目思路分析 目标分析: 1. 将数组中等于val的元素移除 2. 原地移除,意味着时间复杂度为O(n),空间复杂度为O(1) 3. 返回nums中与val值不同的元素个数 思路:双指针 * src:用于扫描元素,从待扫描元素的第一个开始,因此初始下标为0 * dst:指向数组中,最后一个位置正确的元素的下标,因此初始值为-1 * count:记录赋值的次数,赋值的次数即为数组中与val值不同的元素个数,初始值为0 操作: * nums[

By Ne0inhk