自动化测试(Java+eclipse)教程
webdriver环境配置
1.下载chromedriver到本地(一定要选择和自己浏览器相对应的版本chromedriver下载地址)
2.加入到环境变量path中
webdriver工作原理
创建web自动化测试脚本
1.Maven项目创建
File->New->project->(搜索maven)选择maven project
2.安装selenium依赖
选择最多人使用的selenium版本,例如3.141.59,点开,复制如下代码到项目的pom.xml文件中
3.创建文件
在src/test/java下创建com.test包再创建test.java文件
4.编写代码
运行报错:未安装浏览器驱动
5.解决报错
-
下载与浏览器版本相对应的chromedriver,将chromedriver.exe复制到src/test/resources
-
系统设置Chrome驱动文件的路径
6.访问网址
package com.test;import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;public class FirstWebTest {private static ChromeDriver chromeDriver;public static void main(String []args) {openChrome(); }public static void openChrome() {System.setProperty("webdriver.chrome.driver","src/test/resources/chromedriver.exe");// 1. 打开chrome浏览器chromeDriver = new ChromeDriver();// 2. 打开网址chromeDriver.get("https://www.baidu.com");}
}
基本元素定位
// 定位百度的搜索框元素,并且输入数据(id定位)-- 唯一的
chromeDriver.findElement(By.id("kw")).sendKeys("腾讯课堂");// 定位百度的搜索框元素,并且输入数据(name定位) -- 可能重复的
chromeDriver.findElement(By.name("wd")).sendKeys("nihao");
// 如何确定name唯一:在Elements窗口按ctrl+f搜索name名称,查看是否有名称相同的name// 定位百度的搜索框元素,并且输入数据(tagName定位) -- 找到的元素有多个,不推荐
chromeDriver.findElement(By.tagName("input")).sendKeys("111");// 定位百度的搜索框元素,并且输入数据(className定位)
chromeDriver.findElement(By.className("s_ipt")).sendKeys("222");// no such element复合类名的问题
chromeDriver.findElement(By.className("bg s_btn")).click();
chromeDriver.findElement(By.className("s_btn")).click();// 定位"新闻"元素,并且点击(LinkText定位)-->超链接完整文本
chromeDriver.findElement(By.linkText("新闻")).click();// 定位"新闻"元素,并且点击(partialLinkText定位)-->超链接模糊文本
chromeDriver.findElement(By.partialLinkText("闻")).click();
cssSelector元素定位
// cssSelector 元素定位
// (1) tagName定位
chromeDriver.findElement(By.cssSelector("input"));
//(2) id定位
chromeDriver.findElement(By.cssSelector("#kw")).sendKeys("52372");
// (3) className定位
chromeDriver.findElement(By.cssSelector(".s_ipt")).sendKeys("55555");
//一个元素有两个className可一起用
chromeDriver.findElement(By.cssSelector(".bg.s_btn")).click();
// 精确定位
chromeDriver.findElement(By.cssSelector("input[name=\"wd\"]")).sendKeys("1111");
// 多属性精准定位
chromeDriver.findElement(By.cssSelector("input[name=\"wd\"][id=\"kw\"]")).sendKeys("1111");
xpath元素定位
定位元素
//input[@maxlength='100']
用and
//input[@maxlength='100' and @autocomplete='off']通过文本值定位:
完整查询文本
//a[text(),'o123']
模糊查询文本
//a[contains(text(),'o123')]
元素操作API
chromeDriver.findElement(By.id("kw")).sendKeys("12333");
// 等待3s
Thread.sleep(3000);
// 清空文本
chromeDriver.findElement(By.id("kw")).clear();
WebElement webElement1 = chromeDriver.findElement(By.id("kw"));
// 获取元素的标签名 getTagName()
System.out.println("得到元素的标签名:"+webElement1.getTagName());
// 获取元素的属性名 getAttribute
System.out.println("得到元素的maxlength属性:"+webElement1.getAttribute("maxlength"));WebElement webElement2 = chromeDriver.findElement(By.xpath("//a[text()='hao123']"));
// 获取当前元素的文本值 getText()
System.out.println("得到元素的文本值:"+webElement2.getText());
// 查看元素是否显示 isDisplayed()
System.out.println("元素是否显示:"+webElement2.isDisplayed());
WebDriver相关API
// get(String url) 访问指定url页面
chromeDriver.get("https://www.baidu.com");
// getCurrentUrl() 获取当前页面的url地址
System.out.println("当前的URL:"+chromeDriver.getCurrentUrl());
// getTitle() 获取当前页面的标题
System.out.println("当前的标题为:"+chromeDriver.getTitle());
// getPageSource() 获取当前页面源代码
System.out.println("当前页面源代码为:"+chromeDriver.getPageSource());
// quit() 关闭驱动对象以及所有相关窗口
chromeDriver.quit();
chromeDriver.findElement(By.id("kw")).sendKeys("1111");
chromeDriver.findElement(By.id("su")).click();
// getWindowHandle() 返回当前页面句柄
System.out.println("新窗口打开前的句柄:"+chromeDriver.getWindowHandle());
// getWindowHandles() 返回所有由驱动对象打开页面的所有句柄,页面不同,句柄不一样
System.out.println("新窗口打开前的所有句柄:"+chromeDriver.getWindowHandles());
Thread.sleep(2000); // 等待页面元素加载出来
chromeDriver.findElement(By.xpath("//a[contains(text(),'百度百科')]")).click();
Thread.sleep(3000);
System.out.println("新窗口打开后的句柄:"+chromeDriver.getWindowHandle());
System.out.println("新窗口打开后的所有句柄:"+chromeDriver.getWindowHandles());
// close() 关闭当前窗口
chromeDriver.close(); // 只会关闭第一个打开的页面// manage() 获取Options--浏览器菜单操作对象
Options options = chromeDriver.manage();
options.window().maximize();Dimension dimension1 = options.window().getSize();
System.out.println("获得窗口的高度:"+dimension1.getHeight());
System.out.println("获得窗口的高度:"+dimension1.getWidth());Point dimension2 = options.window().getPosition();
System.out.println("获取窗口的X坐标:"+dimension2.getX());
System.out.println("获取窗口的Y坐标:"+dimension2.getY());
// 或
System.out.println("获取窗口的X坐标:"+options.window().getPosition().getX());
// 创建navigate对象
Navigation navigation = chromeDriver.navigate();
Thread.sleep(2000);
// 访问jd
navigation.to("https://www.jd.com");
// 刷新网页
Thread.sleep(2000);
navigation.refresh();
// 回退
Thread.sleep(2000);
navigation.back();
// 前进
Thread.sleep(2000);
navigation.forward();
元素三大等待
硬性等待
代码执行速度太快,UI元素还未显示出来,造成两者不同步,从而元素找不到
隐式等待
// 在driver实例化完成后设置隐式等待
chromeDriver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
chromeDriver.findElement(By.id("kw")).sendKeys("1111");
chromeDriver.findElement(By.id("su")).click();
// Thread.sleep(2000); // 等待页面元素加载出来
chromeDriver.findElement(By.xpath("//a[contains(text(),'百度百科')]")).click();
显式等待
比隐式等待更智能,可只针对单个元素
chromeDriver.findElement(By.id("kw")).sendKeys("1111");
chromeDriver.findElement(By.id("su")).click();// 显式等待--速度更快
WebDriverWait webDriverWait = new WebDriverWait(chromeDriver, 5);
webDriverWait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//a[contains(text(),'百度百科')]")));chromeDriver.findElement(By.xpath("//a[contains(text(),'百度百科')]")).click();
特殊元素定位与操作
模态框alert() & comfirm()
// 访问本地html文件
chromeDriver.get("E:\\homework\\three\\softwareTesting\\自动化测试\\htmlFile\\alert.html");
// 点击按钮
chromeDriver.findElement(By.id("btn")).click();
Thread.sleep(3000);
// switchTo.alert 找到对应的alert弹框
Alert alert = chromeDriver.switchTo().alert();
// 弹框确认
// alert.accept();
// 弹框取消
// alert.dismiss();
// getText() 获取弹出框的文本
System.out.println(alert.getText()); // alert是浏览器控件
iframe
// 进入内嵌页面
chromeDriver.switchTo().frame("bframe");
// 回到默认页面
chromeDriver.switchTo().defaultContent();
实战
元素定位正确却仍然报错:1.页面嵌套iframe;2.未等待元素全部加载完成
// 在mail.qq.com输入qq账号和密码点击登录
chromeDriver.get("https://mail.qq.com/");
chromeDriver.manage().window().maximize();
Thread.sleep(10000);
chromeDriver.switchTo().frame(chromeDriver.findElement(By.xpath("//*[@id=\"QQMailSdkTool_login_loginBox_qq\"]/iframe"))); // 先进入第一个iframe内部的上下文环境中
Thread.sleep(2000);
chromeDriver.switchTo().frame(chromeDriver.findElement(By.xpath("//*[@id=\"ptlogin_iframe\"]"))); // 进入第二个iframe
Thread.sleep(2000);
chromeDriver.findElement(By.id("switcher_plogin")).click();
Thread.sleep(2000);
chromeDriver.findElement(By.id("u")).sendKeys("1781843976@qq.com");
chromeDriver.findElement(By.id("p")).sendKeys("qwe327010");
Thread.sleep(1000);
chromeDriver.findElement(By.id("login_button")).click();
window⭐
// 按顺序切换
driver.get("https://www.le.com/"); // 打开的第一个窗口
driver.manage().window().maximize();
Thread.sleep(1500);
driver.findElement(By.linkText("电影")).click();//1 // 打开的第二个窗口
Thread.sleep(1500);
// 切换到第二个窗口
driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());
Thread.sleep(1500);
driver.findElement(By.className("curr")).click();//2 // 打开的第三个窗口
Thread.sleep(1500);
// 切换到第三个窗口
driver.switchTo().window(driver.getWindowHandles().toArray()[2].toString());// 切换到特定页面
// 先获得所有页面句柄
// 获得所有页面句柄
Set<String> handles = chromeDriver.getWindowHandles();
// 对窗口集合进行遍历
for(String handle : handles) {// 切换句柄chromeDriver.switchTo().window(handle);if (chromeDriver.getTitle().equals("b.html")) {// 如若标题符合,退出循环break;}
}
select下拉框
// 定位时间下拉框
WebElement webElement = chromeDriver.findElement(By.className("c-select-selection"));
// 将WebElement封装成Select对象
Select select = new Select(webElement);
// select下拉框从0开始
select.selectByIndex(1);
Thread.sleep(2000);
select.selectByVisibleText("最近一月");
时间日期控件
// 时间日期控件的处理
chromeDriver.get("https://www.fliggy.com/");
// 时间控件可以直接输入
chromeDriver.findElement(By.xpath("//*[@id=\"J_FlightForm\"]//input[@name=\"depDate\"]")).sendKeys("2023-10-20");
鼠标操作
chromeDriver.get("https://www.treejs.cn/v3/demo/cn/exedit/drag.html");
// 获取需要移动的元素
WebElement sourceElement = chromeDriver.findElement(By.id("treeDemo_2_span"));
// 获取目标元素
WebElement targetElement = chromeDriver.findElement(By.id("treeDemo_3_span"));
// 实例化Actions对象
Actions actions = new Actions(chromeDriver);
actions.clickAndHold(sourceElement).moveToElement(targetElement).release().build().perform();
文件上传
chromeDriver.get("http://www.fanyunedu.com:5000/general/web");
// 直接使用sendkeys,通过浏览器api操作
chromeDriver.findElement(By.xpath("//input[@type='file']")).sendKeys("C:\\Users\\86183\\Pictures\\fraud\\241.jpg");
验证码
验证码防测试
相关文章:

自动化测试(Java+eclipse)教程
webdriver环境配置 1.下载chromedriver到本地(一定要选择和自己浏览器相对应的版本chromedriver下载地址) 2.加入到环境变量path中 webdriver工作原理 创建web自动化测试脚本 1.Maven项目创建 File->New->project->(搜索maven)选择maven pr…...
ThreadFactory 实例创建方式
匿名内部类 private final Executor executor;{ThreadFactory threadFactory new ThreadFactory() {Overridepublic Thread newThread(Runnable r) {Thread t new Thread(r);t.setDaemon(true);return t;}};executor Executors.newFixedThreadPool(shops.size(), threadFac…...

【自动化测试】Pytest框架 —— 跳过测试和失败重试
1、Pytest跳过测试用例 自动化测试执行过程中,我们常常出现这种情况:因为功能阻塞,未实现或者环境有问题等等原因,一些用例执行不了, 如果我们注释掉或删除掉这些测试用例,后面可能还要进行恢复操作&#…...

python 时间加法 输出t分钟后的时间
题目: 现在时间是a点b分,请问t分钟后,是几点几分? 输入: 第一行包含一个整数a 第二行包含一个整数b 第三行包含一个整数t 其中,0≤a≤23,0≤b≤59,0≤t,t分钟后还…...

51单片机-串口通信
文章目录 前言1.基础介绍2.串口实战3.4. 前言 1.基础介绍 常见1,2,3,电源 常用方式1 fosc外部晶振 2.串口实战 3. 4....

JAVA微信端医院3D智能导诊系统源码
医院智能导诊系统利用高科技的信息化手段,优化就医流程。让广大患者有序、轻松就医,提升医疗服务水平。 随着人工智能技术的快速发展,语音识别与自然语言理解技术的成熟应用,基于人工智能的智能导诊导医逐渐出现在患者的生活视角中…...

考研408-计算机网络 第二章-物理层学习笔记及习题
第二章 物理层 一 通信基础 1.1 物理层基本概念 1.1.1 认识物理层 物理层目的:解决如何在连接各种计算机的传输媒体上传输数据比特流,而不是具体的传输媒体。 物理层主要任务:确认与传输媒体接口有关的一些特性,需要进行定义标…...

鸿蒙开发工具的汉化
1、下载汉化包 汉化插件下载地址:Chinese (Simplified) Language Pack / 中文语言包 - IntelliJ IDEs Plugin | Marketplace 百度网盘下载地址:链接:百度网盘 请输入提取码 DevEco Studio是基于IDEA223版本,下载汉化包时请注意…...

14:00面试,14:06就出来了,问的问题有点变态。。。。。。
从小厂出来,没想到在另一家公司又寄了。 到这家公司开始上班,加班是每天必不可少的,看在钱给的比较多的份上,就不太计较了。没想到5月一纸通知,所有人不准加班,加班费不仅没有了,薪资还要降40%…...

如何使用 NFTScan NFT API 在 zkSync 网络上开发 Web3 应用
zkSync 是由 Matter Labs 创建的,是一个以用户为中心的 zk rollup 平台,它是以太坊的第 2 层扩展解决方案,使用 zk-rollups 作为扩展技术,与 optimistic rollups 一样,zk-rollups 将会汇总以太坊主网上的交易并将交易证…...
rust从0开始写项目-读取配置文件
一个项目初始化,总是有几个元素是必不可少的、框架、日志、配置文件等等基本元素。 今天我们主要介绍下怎么获取配置并在全局使用 更多好文。vx. golang技术实验室 专注分享 golang、rust等多语言、中间件及大数据相关内容 Part1一、读取cargo.toml文件内容 Cargo.t…...
Docker的安装以及使用
每次安装Docker都会报一堆错,痛定思痛干脆自己总结一篇!!! Docker的安装 卸载系统自带的旧版本 sudo apt-get remove docker docker-engine docker.io containerd runc 获取软件最新源 sudo apt-get update 安装apt依赖包 s…...

计算机网络学习笔记(五):运输层(待更新)
目录 5.1 概述 5.1.1 TCP协议的应用场景 5.1.2 UDP协议的应用场景 5.2 三大关系 5.2.1 传输层协议和应用层协议之间的关系 5.3 用户数据报协议UDP(User Datagram Protocol) 5.3.1 UDP的特点 5.3.2 UDP的首部 5.4 传输控制协议TCP(Transmission Control Protocol) 5.…...

阿里云99元服务器40G ESSD Entry云盘、2核2G3M带宽配置
阿里云99元服务器新老用户均可以买,你没看错,老用户可以买,活动页面 aliyunfuwuqi.com/go/aliyun 配置为云服务器ECS经济型e实例、2核2G、3M固定带宽、40G ESSD Entry云盘,并且续费不涨价,原价99元即可续费,…...

6个机器学习可解释性框架
1、SHAP SHapley Additive explanation (SHAP)是一种解释任何机器学习模型输出的博弈论方法。它利用博弈论中的经典Shapley值及其相关扩展将最优信贷分配与局部解释联系起来. 举例:基于随机森林模型的心脏病患者预测分类 数据集中每个特征对模型预测的贡献由Shap…...

数据结构——B树
文章目录 B树1. 概念2. B树插入分析3.插入过程4. B树插入实现5.B树验证6. B树性能分析7.B树&B*树8. 小结9. B树的运用MyISAMInnoDB 10. 总结 B树 可以用于查询的数据结构非常的多,比如说二插搜索树、平衡树、哈希表、位图、布隆过滤器,但如果需要存…...

java--String
1.String创建对象封装字符串数据的方式 ①方式一:java程序中的所有字符串文字(例如"abc")都为此类的对象 ②方式二:调用String类的构造器初始化字符串对象。 2.String提供的操作字符串数据的常用方法...
ls命令区别
ls -lh:显示详细信息,其中其中文件大小是显示Kb或Mb。 ls -l:也会显示文件大小,只是显示的是字节。...

经典OJ题:随机链表的复制
目录 题目: 本题的解图关键在于画图与看图! 思路分析: 方法一:暴力求解法。 方法二:插入法 方法解析: 步骤一、插入 步骤二、 处理每一个copy的randdom指针⭐————重点 步骤三、拆卸节点 代码…...

HTML的初步学习
HTML HTML 描述网页的骨架, 标签化的语言. HTML 的执行是浏览器的工作,浏览器会解析 html 的内容,根据里面的代码,往页面上放东西,浏览器的工作归根结底,还是以汇编的形式在CPU上执行. 浏览器对于html语法格式的检查没有很严格,即使你写的代码有一些不合规范之处,浏览器也会尽可…...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...

【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...