目录
- 1. 什么是自动化为什么要做自动化
- 2. 为什么选择selenium作为我使用的web自动化工具
- 3. 什么是驱动?驱动的工作原理是什么
- 5. 第一个自动化程序演示
- 6. selenium基本语法
- 6.1 定位元素的方法
- 6.2 操作页面元素
- 6.3 等待
- 6.4 信息打印
- 获取当前页面句柄,窗口切换
- 6.5 导航
- 6.6 alert弹窗
- 6.7 针对鼠标,键盘的操作
- 6.8 选择框
- 6.9 文件上传
- 6.10 屏幕截图
1. 什么是自动化为什么要做自动化
自动化测试能代替一部分的手工测试,自动化测试可以提高测试效率;随着功能的增加,版本越来越多,版本回归的压力也越来越大,所以仅仅通过人工测试来回归所有的版本肯定是不现实的;随意需要借助自动化工具来进行回归测试
selenium依赖:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.0.0</version>
</dependency>
2. 为什么选择selenium作为我使用的web自动化工具
选择selenium的原因是:
● 开源免费
● 支持多浏览器,如Chrome,Firefox,IE,Safari
● 支持多系统,如Linux,Windows,macOS
● 支持多语言,如Java,Python…
● selenium包底层有很多可现成使用的API
环境部署需要:
● selenium工具包(pom导入)
● Chrome浏览器
● Chromedriver谷歌驱动
● jdk1.8
3. 什么是驱动?驱动的工作原理是什么
驱动:
骑车里面有驱动,两轮驱动,四轮驱动,可以让骑车跑起来
计算机也有驱动程序,可以驱动计算机和设备工作起来
打开浏览器也需要驱动,人工测试的情况下(人工手动的驱动来打开浏览器)
自动化来说,代码不能直接打开浏览器,需要借助驱动程序来协助打开浏览器
代码可以驱使驱动来打开浏览器:selenium 驱动 浏览器三者之间的关系:
webdriver驱动是一个服务器的角色,地址是 127.0.0.1 端口号是:9515
5. 第一个自动化程序演示
● 自动化测试可以简单理解为把人工手动进行的操作通过代码来实现出来,通过代码来实现模拟人工的一系列操作
使用自动化脚本来进行关键词“迪丽热巴”的搜索:
- 首先创建一个普通的maven工程,并在test包下编写自动化测试代码
在pom文件中导入selenium的依赖
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.0.0</version>
</dependency>
编写一个启动类
public class RunAutoTest {
public static void main(String[] args) throws InterruptedException {
FirstAutoTest firstAutoTest=new FirstAutoTest();
firstAutoTest.dilireba_test();
}
}
编写进行自动化测试的类和相应代码
public class FirstAutoTest {
// 第一个简单的自动化实例
public void dilireba_test() throws InterruptedException {
// 创建浏览器驱动来操作浏览器
ChromeDriver chromeDriver=new ChromeDriver();
Thread.sleep(3000); // 手动睡眠一下,让程序能够被我们观察到,不至于执行太快
//输入百度地址
chromeDriver.get("https://www.baidu.com");
Thread.sleep(3000);
// 找到百度输入框,并输入关键词“迪丽热巴”
chromeDriver.findElement(By.cssSelector("#kw")).sendKeys("迪丽热巴");
Thread.sleep(3000);
// 找到点击搜索,点击
chromeDriver.findElement(By.cssSelector("#su")).click();
Thread.sleep(3000);
//操作完成释放对象
chromeDriver.quit();
}
}
自动化测试进行成功:
6. selenium基本语法
6.1 定位元素的方法
使用css选择器(selector)
public void dingweiTest(){
String text=chromeDriver.findElement(By.cssSelector("从网页邮件检查复制对应元素css selector")).getText();
System.out.println(text);
// 即可找到对应的元素
}
使用xpath进行定位:
语法:
层级:/次级 //跳级(子级)
属性
函数
chromeDriver.findElement(By.xpath("复制元素xpath路径")).sendKeys("xxxxxx");
定位元素要唯一
6.2 操作页面元素
- 点击:click
chromeDriver.findElement(By.cssSelector("#su")).click();
- 提交:submit
chromeDriver.findElement(By.cssSelector("#su")).submit();
● click和submit都可以操作按钮
● 可以click的不一定都可以submit
● 页面任何一个元素都可以click
● selenium官方文档里面不建议使用submit
模拟按键输入:
chromeDriver.findElement(By.xpath("复制元素xpath路径")).sendKeys("xxxxxx");
清除对象输入的文本内容:clear
chromeDriver.findElement(By.cssSelector("#kw")).sendKeys("xxxxxxx")
chromeDriver.findElement(By.cssSelector("#kw")).clear();
获取文本:getText()
String text=chromeDriver.findElement(By.cssSelector("从网页邮件检查复制对应元素css selector")).getText();
System.out.println(text);
不是说页面上所有可以看见的文字都属于文本,有一些是属于对应的属性值,如下面的 “百度一下”
文本是写在html标签外面的
获取html属性值:getAttribute(“key”)
String text=chromeDriver.findElement(By.cssSelector("从网页邮件检查复制对应元素css selector")).getAttribute("key");
6.3 等待
代码执行速度是非常快的,前端页面渲染的速度相对慢一点,可能导致的结果是:代码已经执行到下一步了,页面还没有渲染出来,元素找不到而报错
等待又分为三个:强制等待,隐式等待,显式等待
● 强制等待:让程序暂停一会,等待指定的时间之后继续执行下一步
线程sleep就属于一种强制等待
优点:语法简单,适合调试的时候用
缺点:需要等待固定的时间,造成自动化测试的时间大量消耗,大大的减少了自动化的测试效率
● 隐式等待:在规定的时间范围内,轮询等待元素出现之后就立即结束,如果在规定的时间内元素仍然没有出现,则会抛出一个noSuchElement异常
public void yinshiWait(){
// 隐式等待
chromeDriver.get("https://www.baidu.com");
chromeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3)); // 超时时间:3s
chromeDriver.findElement(By.cssSelector("#kw")).sendKeys("迪丽热巴");
chromeDriver.findElement(By.cssSelector("#su")).click();
chromeDriver.findElement(By.cssSelector("#\\32 > div > div > div > a > div > p > span > span:nth-child(1)"));
}
● 隐式等待作用在webdriver整个生命周期(只要没有走到driver.quit,即没有退出浏览器,隐式等待都是一直存在的)
优点:节省了大量的等待时间,元素展示之后就可以直接执行下一步了,执行效率高
缺点:需要等待页面所有的元素都展现才会执行下一步,仍然会有额外的浪费
● 显示等待
可以针对页面的某一个元素进行等待,有针对性的等待,进一步减少浪费
WebDriverWait wait=new WebDriverWait(chromeDriver,Duration.ofSeconds(3));
WebDriverWait(第一个参数:webdriver对象,第二个参数:Duration.方法,用于设置强制等待的时间)
显示等待可以使用selenium里的一个类,class ExpectedConditions ,类里面提供了很多方法可以用来调试
public void xianshiWait(){
// 显示等待
chromeDriver.get("https://www.baidu.com");
chromeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
chromeDriver.findElement(By.cssSelector("#kw")).sendKeys("迪丽热巴");
chromeDriver.findElement(By.cssSelector("#su")).click();
// chromeDriver.findElement(By.cssSelector("#\\32 > div > div > div > a > div > p > span > span:nth-child(1)"));
WebDriverWait wait=new WebDriverWait(chromeDriver,Duration.ofSeconds(3));
wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.cssSelector("#\\32 > div > div > div > a > div > p > span > span:nth-child(1)")));
// until 的意思就是等待直到 某个页面元素加载完成 即可
// ExpectedConditions.presenceOfAllElementsLocatedBy 查看页面元素是否存在,如果存在条件通过,程序结束
// 不存在报找不到对应元素的异常
}
也可以进行元素对应的文本信息进行校验 textToBe :
public void xianshiWait(){
// 显示等待
chromeDriver.get("https://www.baidu.com");
chromeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
chromeDriver.findElement(By.cssSelector("#kw")).sendKeys("迪丽热巴");
chromeDriver.findElement(By.cssSelector("#su")).click();
// chromeDriver.findElement(By.cssSelector("#\\32 > div > div > div > a > div > p > span > span:nth-child(1)"));
WebDriverWait wait=new WebDriverWait(chromeDriver,Duration.ofSeconds(3));
//wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.cssSelector("#\\32 > div > div > div > a > div > p > span > span:nth-child(1)")));
wait.until(ExpectedConditions.textToBe(By.cssSelector("#\\31 > div > div > div > div > div.cos-row.row-text_Johh7.row_5y9Az > div > div:nth-child(3) > span")
,"中国内地影视女演员"));
// until 的意思就是等待直到 某个页面元素加载完成 即可
// ExpectedConditions.presenceOfAllElementsLocatedBy 查看页面元素是否存在,如果存在条件通过,程序结束
// 不存在报找不到对应元素的异常
}
校验成功程序才通过,不成功则报错:
校验成功
code 0 :执行成功
until:等待什么时候为止,即等待括号的条件满足为止,如果条件在指定时间内没有满足,就抛出异常
显示等待:
优点:可以针对页面的某一个元素进行等待,有针对性的等待,进一步减少浪费
同时执行隐式等待和显式等待,最终等待的时间是多少测试
public void yin_xian_waitTest(){
chromeDriver.get("https://www.baidu.com");
// 同时使用隐式等待和显式等待,假如隐式等待5s,显式等待10s,测试最终等待是几秒
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(simpleDateFormat.format((System.currentTimeMillis())));
chromeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));// 隐式等待5s
WebDriverWait wait=new WebDriverWait(chromeDriver,Duration.ofSeconds(10)); // 显式等待10s
try {
wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#xxxx 等待一个不存在的元素")));
}catch (Exception e){
System.out.println("nosunelement");
}
System.out.println(simpleDateFormat.format((System.currentTimeMillis())));
}
执行结果:
可以看出代码中同时执行隐式等待和显式等待,最终等待时间是显式等待所设置的时间(也可能是11s…)
● 不建议同时使用隐式等待和显式等待,等待时间不可控会出差错
6.4 信息打印
准备工作,定义开始和结束方法,开始都打开百度首页进行测试:
public class AutoTest2 {
private final ChromeDriver chromeDriver=new ChromeDriver();
public void startDriver(){
chromeDriver.get("https://www.baidu.com");
// 设置一个隐式等待,避免页面元素找不到代码执行结束报错
chromeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
}
// 自动化测试代码
///
public void quitDriver(){
chromeDriver.quit();
}
}
- 打印标题
- 打印当前页面URL
获取当前页面句柄,窗口切换
每个页面都有一个唯一标识,称为句柄,首先需要知道当前页面的句柄是什么
public void windowTest(){
// 每个页面都有一个唯一标识,称为句柄
// 获取当前页面的句柄
String cur_windowHandle = chromeDriver.getWindowHandle();
System.out.println(cur_windowHandle);
}
打开百度首页之后,点击新闻超链接跳转页面,再次尝试获取当前页面的句柄外加上当前所有页面的句柄
public void windowTest(){
// 每个页面都有一个唯一标识,称为句柄
// 获取当前页面的句柄
String cur_windowHandle = chromeDriver.getWindowHandle();
System.out.println(cur_windowHandle);
chromeDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
String cur_windowHandle2 = chromeDriver.getWindowHandle();
System.out.println(cur_windowHandle2);
// 打印当前所有页面的句柄
Set<String> windowHandles = chromeDriver.getWindowHandles();
for (String window:windowHandles) {
System.out.println(window);
}
}
可以得知点击新闻超链接后,程序认为当前页面依旧停留在百度首页,没有自动停留在新打开的百度新闻页面
切换到最新的页面:
chromeDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
String windowHandle = chromeDriver.getWindowHandle();
// 需要让程序知道当前页面是停留在哪一个页面
// selenium 对每一个标签页都给了一个唯一标识,称之为句柄
// 打印当前所有页面的句柄
Set<String> windowHandles = chromeDriver.getWindowHandles();
for (String window:windowHandles) {
if (window!=windowHandle){
// 跳转到该页面
chromeDriver.switchTo().window(window);
}
}
此时就可以进行不同页面的标题和URL打印了:
public void printTest(){
// 打印标题
String title = chromeDriver.getTitle();
System.out.println(title);
// 打印当面页面URL
String currentUrl = chromeDriver.getCurrentUrl();
System.out.println(currentUrl);
// 进入百度首页以后,点击新闻超链接
chromeDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
String windowHandle = chromeDriver.getWindowHandle();
// 需要让程序知道当前页面是停留在哪一个页面
// selenium 对每一个标签页都给了一个唯一标识,称之为句柄
// 打印当前所有页面的句柄
Set<String> windowHandles = chromeDriver.getWindowHandles();
for (String window:windowHandles) {
if (window!=windowHandle){
// 跳转到该页面
chromeDriver.switchTo().window(window);
}
}
// 打印标题
String title2 = chromeDriver.getTitle();
System.out.println(title2);
// 打印当面页面URL
String currentUrl2 = chromeDriver.getCurrentUrl();
System.out.println(currentUrl2);
}
窗口切换
public void windowTest2() throws InterruptedException {
// 窗口最大化
chromeDriver.manage().window().maximize(); // 窗口最大化
Thread.sleep(2000);
chromeDriver.manage().window().minimize(); // 窗口最小化
Thread.sleep(2000);
chromeDriver.manage().window().setSize(new Dimension(1000,800)); // 窗口设置指定尺寸
Thread.sleep(2000);
// 执行js脚本语言,进行窗口置顶 置低操作
chromeDriver.executeScript("window.scroll(0,document.body.scrollHeight)");
Thread.sleep(2000);
chromeDriver.executeScript("window.scroll(0,document.body.scrollTop)");
Thread.sleep(2000);
}
6.5 导航
selenium里提供了navigate接口来实现页面的导航
前进,后退
public void navigateTest() throws InterruptedException {
Thread.sleep(2000);
chromeDriver.findElement(By.cssSelector("#page > div:nth-child(1) > div.tabs-wrap > ul > li:nth-child(2) > a")).click();
Thread.sleep(2000);
chromeDriver.navigate().back();
Thread.sleep(2000);
chromeDriver.navigate().forward();
Thread.sleep(2000);
}
6.6 alert弹窗
selenium提供 switch_to_alert方法:捕获弹出对话框(可以定位alert、confirm、prompt对话框)
注意使用 Alert alert=chromeDriver.switchTo().alert(); 抓取 alert 弹窗时候记得使用强制等待 Thread.sleep(),避免因为代码执行速度过快导致弹窗还没加载完成就结束代码执行而出现报错
可以在前端代码里定位到的普通弹窗都可以使用driver.findElement()方法来定位元素
但是针对alert警告弹窗:
不能在前端代码里定位到该元素
需要使用selenium中提供的alert接口进行处理
针对alert警告弹窗代码处理如下:
public void alertTest() throws InterruptedException {
chromeDriver.get("http://124.220.134.3:8085/login.html");
// 设置一个隐式等待,避免页面元素找不到代码执行结束报错
chromeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
Thread.sleep(1000);
// 警告弹窗alert的处理
chromeDriver.findElement(By.cssSelector("#submit")).click(); // 切换到警告弹窗上
Alert alert=chromeDriver.switchTo().alert(); // 定位弹出对话框
// 点击确认按钮
Thread.sleep(1000);
alert.accept(); // 确认
// alert.dismiss(); // 取消
Thread.sleep(1000);
}
针对可以输入的提示弹窗进行处理:
public void alertTest() throws InterruptedException {
chromeDriver.get("http://124.220.134.3:8085/login.html");
// 设置一个隐式等待,避免页面元素找不到代码执行结束报错
chromeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
Thread.sleep(1000);
// 警告弹窗alert的处理
chromeDriver.findElement(By.cssSelector("#submit")).click(); // 切换到警告弹窗上
Thread.sleep(1000);
Alert alert=chromeDriver.switchTo().alert(); // 定位弹出对话框
alert.sendKeys("xxxxxxxx"); // 提示弹窗处理
Thread.sleep(1000);
alert.accept();
Thread.sleep(1000);
}
6.7 针对鼠标,键盘的操作
selenium提供了Actions接口来针对鼠标和键盘进行操作
- 鼠标移动到指定的元素上
public void mouse_keyBox_test() throws InterruptedException {
// 模拟鼠标移动到我们想要的元素上,并点击
WebElement element = chromeDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)"));
Actions actions=new Actions(chromeDriver);
actions.clickAndHold(element).perform();
Thread.sleep(3000);
}
注意 clickAndHold 并不会实现点击效果,不加perform就不会进行演示
需要进行点击操作要加 actions.click(element).perform(); 这一行代码
public void mouse_keyBox_test() throws InterruptedException {
// 模拟鼠标移动到我们想要的元素上,并点击
WebElement element = chromeDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)"));
Actions actions=new Actions(chromeDriver);
actions.clickAndHold(element).perform();
actions.click(element).perform();
Thread.sleep(3000);
}
针对键盘的操作:
6.8 选择框
selenium提供了select接口针对选择框来进行操作:
public void selectTest() throws InterruptedException {
Thread.sleep(1000);
WebElement element = chromeDriver.findElement(By.cssSelector("#xxx"));// 先找到选择框对应的元素
Select select=new Select(element);
select.selectByIndex(0); // 通过索引找选项,索引从0开始计数
select.selectByValue("value"); // 通过value值进行选择
select.selectByVisibleText("VisibleText"); // 通过可见文本进行选择(选择框里面的文本内容)
Thread.sleep(1000);
}
6.9 文件上传
页面中点击文件上传会弹出系统窗口,selenium不能够操作系统窗口
public void fileUpload() throws InterruptedException{
Thread.sleep(1000);
WebElement element= chromeDriver.findElement(By.cssSelector("#xxx")); // 先定位到上传文件按钮对应的元素
// 不要进行点击操作,直接进行 sendKeys 输入想要上传的文件路径
element.sendKeys("D:\\xxxxx\\xxxxx\\xxxx\\xxx.html");
Thread.sleep(1000);
}
通过 sendKeys() 方法输入想要上传的文件路径以及文件名,就能够达到文件上传的目的
6.10 屏幕截图
原因:代码的执行速度比页面渲染的速度要快得多,就需要使用屏幕截图来判断留证等;
public void screenShotTest() throws IOException {
chromeDriver.findElement(By.cssSelector("#kw")).sendKeys("selenium");
chromeDriver.findElement(By.cssSelector("#su")).click();
// 屏幕截图
File screenshot = chromeDriver.getScreenshotAs(OutputType.FILE);
// 将屏幕截图文件 screenshot 保存到指定的路劲下
File curFile=new File("./src/test/autoPic/my.png");
FileUtils.copyFile(screenshot,curFile);
chromeDriver.findElement(By.cssSelector("#\\32 > div > div > h3 > a"));
}
此时屏幕截图的文件就保存到了我指定的目录下:
屏幕截图成功:
- selenium基础语法完 ~