自动化测试(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语法格式的检查没有很严格,即使你写的代码有一些不合规范之处,浏览器也会尽可…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
