一 : 什么是自动化?
自动化可以有效减少人力的消耗 , 同时提高测试的质量和效率 . 例如在回归测试中 , 随着版本越来越多 , 版本回归的压力也越来越大 , 仅仅通过人工测试来回归所以版本显然是不现实的 , 所以我们需要借助自动化测试 .
二 : 自动化测试的分类
三 : selenium
这是一款web自动化测试工具 , 它有如下优点 :
- 开源免费 ;
- 支持多浏览器 , 如Chrome , Firefox , IE浏览器…
- 支持多系统 , 如Linux , Windows , MacOs
- 支持多语言 , 如Java , Python , JS
- selenium包提供了很多可供测试使用的API .
四 : 环境部署
java+selenium环境搭建 :
1.下载Chrome浏览器(注意版本为110.0之前的)
2.下载谷歌驱动(谷歌驱动要与谷歌浏览器版本一致)
注意 : 与自己浏览器版本相对应 !!!
3.解压下载好的驱动压缩包,将下载好的chromedriver.exe放到java系统环境变量下 :
此处是我电脑中的路径 :
五 : 示例
5.1 简单自动化实例
导入selenium包 :
编写代码 :
package com.autotest;
public class RunAutoTest {
public static void main(String[] args) throws InterruptedException {
FirstAutoTest firstAutoTest = new FirstAutoTest();
firstAutoTest.pengyuyanTest();
}
}
package com.autotest;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.HashMap;
public class FirstAutoTest {
public void pengyuyanTest() throws InterruptedException {
//1.创建驱动实例,创建会话(打开浏览器)
ChromeDriver driver = new ChromeDriver();
Thread.sleep(2000);
//2.在浏览器输入百度网址,访问百度首页
driver.get("https://www.baidu.com");
Thread.sleep(2000);
//3.找到百度首页输入框元素,输入关键词"彭于晏"
driver.findElement(By.cssSelector("#kw")).sendKeys("彭于晏");
Thread.sleep(2000);
//4.找到百度首页"百度一下"按钮,并点击一下
driver.findElement(By.cssSelector("#su")).click();
Thread.sleep(2000);
//5.结束会话
driver.quit();
}
}
运行效果 :
5.2 selenium常用方法
比如我们选择"搜索网页"这个元素 :
然后使用复制到的selector进行查找 :
比如现在 , 我定位到新闻元素 , 并复制其xpath :
此时共查找到10条元素 , 这不符合我的预期 , 我们需要手动地修改xpath , 以定位到具体一条新闻 , 比如 :
设置为li[5] , 此时就定位到了东航事件这一条具体的新闻了 !
六 : 常见的元素操作
6.1 输入文本
仅适用于文本字段和内容可编辑的元素 .
sendKeys
package com.autotest;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class SecondAutoTest {
ChromeDriver driver = new ChromeDriver();
public void ElementTest() throws InterruptedException {
//1.跳转至百度首页
driver.get("https://www.baidu.com");
//2.得到要输入文本的元素并输入"蔡徐坤"
Thread.sleep(2000);
WebElement ele = driver.findElement(By.cssSelector("#kw"));
ele.sendKeys("蔡徐坤");
Thread.sleep(2000);
driver.quit();
}
}
也可以合起来写 :
package com.autotest;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class SecondAutoTest {
ChromeDriver driver = new ChromeDriver();
public void ElementTest() throws InterruptedException {
//1.跳转至百度首页
driver.get("https://www.baidu.com");
//2.得到要输入文本的元素并输入"蔡徐坤"
Thread.sleep(2000);
driver.findElement(By.cssSelector("#kw")).sendKeys("蔡徐坤");
Thread.sleep(2000);
driver.quit();
}
}
6.2 点击
click
//3.点击
driver.findElement(By.cssSelector("#su")).click();
6.3 提交
submit
仅适用于表单提交 , 不推荐使用 .
//提交
driver.findElement(By.cssSelector("#su")).submit();
6.4 清除
clear
driver.findElement(By.cssSelector("#kw")).sendKeys("蔡徐坤");
driver.findElement(By.cssSelector("#kw")).clear();
driver.findElement(By.cssSelector("#kw")).sendKeys("坤坤");
6.5 获取文本
getText
String text =
driver.findElement(By.cssSelector("#hotsearch-content-wrapper > li:nth-child(3) > a > span.title-content-title")).getText();
System.out.println(text);
此处的内容是文本 , 我们可以直接获取到 ; 那么形如"百度一下"这样的按钮内的文字 , 我们就不能直接获取了 , 而是要通过获取属性的方式 :
System.out.println("type = " + driver.findElement(By.cssSelector("#su")).getAttribute("type"));
System.out.println("id = " + driver.findElement(By.cssSelector("#su")).getAttribute("id"));
System.out.println("value = " + driver.findElement(By.cssSelector("#su")).getAttribute("value"));
System.out.println("class = " + driver.findElement(By.cssSelector("#su")).getAttribute("class"));
6.6 获取页面标题和URL
//获取页面标题和URL
System.out.println(driver.getTitle());
System.out.println(driver.getCurrentUrl());
driver.findElement(By.cssSelector("#kw")).sendKeys("只因");
driver.findElement(By.cssSelector("#su")).click();
Thread.sleep(2000);
System.out.println("搜索之后:");
System.out.println(driver.getTitle());
System.out.println(driver.getCurrentUrl());
借助前面学习的内容 , 我们尝试对"博客系统"进行登录测试 :
package com.autotest;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
public class BlogAutoTest {
ChromeDriver driver = new ChromeDriver();
public void loginTest() throws InterruptedException {
driver.get("http://121.4.87.61:8001/login.html");
Thread.sleep(2000);
driver.findElement(By.cssSelector("#username")).sendKeys("老金在这");
Thread.sleep(2000);
driver.findElement(By.cssSelector("#password")).sendKeys("123456");
Thread.sleep(2000);
driver.findElement(By.cssSelector("#submit")).click();
Thread.sleep(2000);
driver.quit();
}
}
成功实现登录 !
七 : 窗口
7.1 窗口大小设置
//窗口
public void windowTest() throws InterruptedException {
driver.get("https://www.baidu.com");
//窗口大小设置
Thread.sleep(2000);
driver.manage().window().maximize();
Thread.sleep(2000);
driver.manage().window().minimize();
Thread.sleep(2000);
driver.manage().window().fullscreen();
Thread.sleep(2000);
driver.manage().window().setSize(new Dimension(1000,500));
driver.quit();
}
7.2 窗口切换
打开百度首页,点击图片超链接进入到百度图片首页,获取百度图片页面的“百度一下”按钮 :
//点击"图片"跳转
driver.findElement(By.cssSelector("#s-top-left > a:nth-child(6)")).click();
driver.findElement(By.cssSelector("#homeSearchForm > span.s_btn_wr > input"));
此时出现问题了 !!! 这是因为浏览器每次打开标签页 , 会自动给这个标签页加上一个"句柄" , 当我们打开另外一个链接时 , 没有指明是在哪个页面选择"百度一下"这个元素 , 自然会出现找不到元素的错误 .
先获取到所有页面的句柄 :
//点击"图片"跳转
driver.findElement(By.cssSelector("#s-top-left > a:nth-child(6)")).click();
Set<String> handles= driver.getWindowHandles();
for (String handle : handles) {
System.out.println(handle);
}
果然有两个句柄 .
此时我们这样做 :
driver.get("https://www.baidu.com");
//获取百度页面的句柄
String curHandle = driver.getWindowHandle();
Thread.sleep(2000);
//点击"图片"跳转
driver.findElement(By.cssSelector("#s-top-left > a:nth-child(6)")).click();
Thread.sleep(2000);
Set<String> handles= driver.getWindowHandles();
for (String handle : handles) {
if(handle != curHandle) {
driver.switchTo().window(handle);
}
}
driver.findElement(By.cssSelector("#kw")).sendKeys("章若楠");
Thread.sleep(2000);
driver.findElement(By.cssSelector("#homeSearchForm > span.s_btn_wr > input")).click();
Thread.sleep(2000);
7.3 屏幕截图
现在有这样一段代码 , 在百度浏览器中输入"章若楠" , 之后选择页面中的"早年经历"元素 :
driver.get("https://www.baidu.com");
//代码执行速度 vs 页面渲染速度
driver.findElement(By.cssSelector("#kw")).sendKeys("章若楠");
driver.findElement(By.cssSelector("#su")).click();
driver.findElement(By.cssSelector("#\\31 > div > div > div > div > div:nth-child(3) > div > div.baike-slink-wrapper_7k8vl.cu-pb-xs-lg.baike-slink-wrapper-pc_4qIWd > div > div:nth-child(1) > a > button > div")).click();
执行出错 , 我们可以通过屏幕截图的方式排查原因 :
driver.get("https://www.baidu.com");
//代码执行速度 vs 页面渲染速度
driver.findElement(By.cssSelector("#kw")).sendKeys("章若楠");
driver.findElement(By.cssSelector("#su")).click();
//屏幕截图
File srcFile = driver.getScreenshotAs(OutputType.FILE);
//生成截图的保存路径
String fileName = UUID.randomUUID().toString() + ".png";
//将截图拷贝至保存路径下
FileUtils.copyFile(srcFile,new File(fileName));
driver.findElement(By.cssSelector("#\\31 > div > div > div > div > div:nth-child(3) > div > div.baike-slink-wrapper_7k8vl.cu-pb-xs-lg.baike-slink-wrapper-pc_4qIWd > div > div:nth-child(1) > a > button > div")).click();
运行代码 , 查看屏幕截图 :
可以看出此时页面渲染尚未完成 , 自然找不到"早年经历"这样一个页面元素了 . 修改代码 :
driver.get("https://www.baidu.com");
//代码执行速度 vs 页面渲染速度
driver.findElement(By.cssSelector("#kw")).sendKeys("章若楠");
Thread.sleep(3000);
driver.findElement(By.cssSelector("#su")).click();
Thread.sleep(3000);
//屏幕截图
File srcFile = driver.getScreenshotAs(OutputType.FILE);
//生成截图的保存路径
String fileName = UUID.randomUUID().toString() + ".png";
//将截图拷贝至保存路径下
FileUtils.copyFile(srcFile,new File(fileName));
driver.findElement(By.cssSelector("#\\31 > div > div > div > div > div:nth-child(3) > div > div.baike-slink-wrapper_7k8vl.cu-pb-xs-lg.baike-slink-wrapper-pc_4qIWd > div > div:nth-child(1) > a > button > div")).click();
Thread.sleep(3000);
此时程序正常退出 :
屏幕截图的显示也没问题 !
非常地对对 !!!
这种情况下怎么不用"窗口切换"了 ? 我们来看看这个新页面中"早年经历"的selector选择器 :
在当前页面中有唯一匹配 :
在百度首页中则没有任何一个匹配 !
而"百度一下"这个选项在在两个页面都有匹配 , 所以此时就需要用到"句柄"了 .
八 : 浏览器导航
//浏览器导航
public void ChromeGPS() {
//请求百度网址的简便写法
driver.get("https://www.baidu.com");
//请求百度网址的完整写法
driver.navigate().to("https://www.baidu.com");
//回退到访问百度网址之前的状态
driver.navigate().back();
//前进
driver.navigate().forward();
//刷新页面
driver.navigate().refresh();
//退出
driver.quit();
}
九 : 弹窗
弹窗通常有3种:Alert类型弹框、Confirm类型弹框、Prompt类型弹框 :
Alert弹窗:只有信息及确认按钮
Confirm弹窗:在Alert弹窗基础上增加了取消按钮
Prompt类型弹框:在Confirm的基础上增加了可输入文本内容的功能
//弹窗
public void AlertControl() throws InterruptedException {
//1.打开页面
driver.get("file:///C:/java-2023/Test/autotest/target/static/alert.html");
Thread.sleep(2000);
//2.打开弹窗
driver.findElement(By.cssSelector("body > button")).click();
Thread.sleep(2000);
//3.切换到弹窗进行弹窗的处理
Alert alert = driver.switchTo().alert();
Thread.sleep(2000);
//4.1弹窗确认
alert.accept();
Thread.sleep(2000);
//4.2弹窗取消
//alert.dismiss();
//5.退出
driver.quit();
}
展示输入文本的效果 :
public void AlertControl() throws InterruptedException {
//1.打开页面
driver.get("file:///C:/java-2023/Test/autotest/target/static/Prompt.html");
Thread.sleep(2000);
//2.打开弹窗
driver.findElement(By.cssSelector("body > input[type=button]")).click();
Thread.sleep(2000);
//3.切换到弹窗进行弹窗的处理
Alert alert = driver.switchTo().alert();
Thread.sleep(2000);
//4.输入文本
alert.sendKeys("输入测试文本!");
//5.弹窗确认
alert.accept();
Thread.sleep(2000);
//5.退出
driver.quit();
}
十 : 选择框
public void selectorControl() throws InterruptedException {
driver.get("file:///C:/java-2023/Test/autotest/target/static/select.html");
Thread.sleep(2000);
//1.找到选择框元素
WebElement ele = driver.findElement(By.cssSelector("#ShippingMethod"));
//2.创建选择框对象
Select select = new Select(ele);
//3.进行选择
//3.1根据文本框来选择
//select.selectByVisibleText("USPS Priority Mail Insured ==> $9.25");
//3.2根据属性值来选择
//select.selectByValue("9.25");
//3.3根据序号来选择
select.selectByIndex(5);
Thread.sleep(2000);
driver.quit();
}
十一 : 执行脚本
public void scriptControl() throws InterruptedException {
driver.get("https://image.baidu.com/");
Thread.sleep(2000);
//执行js代码让页面置底
driver.executeScript("document.documentElement.scrollTop=500");
Thread.sleep(2000);
//执行js代码让页面置顶
driver.executeScript("document.documentElement.scrollTop=0");
Thread.sleep(2000);
driver.quit();
}
十二 : 文件上传
@Test
public void fileUpload() throws InterruptedException {
driver.get("file:///C:/java-2023/Test/autotest/target/static/upload.html");
Thread.sleep(2000);
driver.findElement(By.cssSelector("body > div > div > input[type=file]")).
sendKeys("C:\\Users\\86177\\Desktop\\picture\\star\\@(Z0FI7@Q2NR5U({PHQAF)A.jpg");
Thread.sleep(2000);
driver.quit();
}
十三 : 浏览器参数设置—无头模式
//无头模式
public void ResultTest() {
//先创建选项对象,然后再设置浏览器参数
ChromeOptions options = new ChromeOptions();
options.addArguments("-headless");
driver.get("https://www.baidu.com");
driver.findElement(By.cssSelector("#kw")).sendKeys("章若楠");
driver.findElement(By.cssSelector("#su")).click();
driver.quit();
}
执行成功 !
十四 : JUnit
本文到此结束 !