此篇博客与上一篇【测试】自动化测试有很多重合的地方,我就说这篇写着写着感觉好像之前写过,果然在草稿箱里找到了两年前写的类似的博客 T-T,一起结合着看吧......
目录
[一. 概念](#一. 概念)
[1.1 自动化测试分类](#1.1 自动化测试分类)
[1.2 自动化测试金字塔](#1.2 自动化测试金字塔)
[二. web自动化测试](#二. web自动化测试)
[三. Selenium](#三. Selenium)
[3.1 元素的定位](#3.1 元素的定位)
[3.2 操作测试对象](#3.2 操作测试对象)
[3.3 窗口](#3.3 窗口)
[3.4 屏幕截图](#3.4 屏幕截图)
[3.5 等待](#3.5 等待)
[3.6 浏览器导航](#3.6 浏览器导航)
[3.7 弹窗](#3.7 弹窗)
[3.8 文件上传](#3.8 文件上传)
[3.9 浏览器参数设置](#3.9 浏览器参数设置)
一. 概念
常见误区:
自动化测试可以取代人工测试 ❌️
自动化测试可以大幅度降低工作量 ❌️
分类:
接口自动化 UI自动化(客户端界面测试/web界面测试)
二. web自动化测试
手工测试:
1) 打开浏览器
3)找到输入框,输入关键词"字节跳动"
4)找到点击按钮并点击
5)关闭浏览器
自动化测试:同手工测试流程程序想要打开打开浏览器,就需要安装web驱动(即WebDriver),以本地化方式驱动浏览器。
安装驱动管理:WebDriverManager 是一个开源的Java库,不需要手动下载驱动程序,只需要在程序中下载对应的依赖(Maven pom.xml),驱动管理程序会自动下载正确的驱动。
三. Selenium
java
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class FirstTest {
// 测试百度搜索关键词:字节跳动
void test01() throws InterruptedException {
// 1. 打开浏览器
WebDriverManager.chromedriver().setup();
// 增加浏览器配置,创建驱动对象要强制执行指定允许访问所有链接
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver driver = new ChromeDriver(options);
Thread.sleep(3000);
// 2. 输入网址:https://222.baidu.com
driver.get("https://www.baidu.com");
Thread.sleep(3000);
// 3. 找到输入框,输入关键词:字节跳动
driver.findElement(By.cssSelector("#kw")).sendKeys("字节跳动");
Thread.sleep(3000);
// 4. 找到百度一下按钮,点击
driver.findElement(By.cssSelector("#su")).click();
Thread.sleep(3000);
// 5. 关闭浏览器
driver.close();
}
}
3.1 元素的定位
1)cssSelector: #kw
2)xpath: //*[@id="kw"]
//* 获取页面所有节点
//[指定节点] 获取页面指定节点
/ 获取节点中的直接子节点
//*[@...] 实现节点属性的匹配
java
// 实现元素定位
void test02() throws InterruptedException {
createDriver();
// 定位"百度热搜"
driver.findElement(By.cssSelector("#s-hotsearch-wrapper > div > a > div > i:nth-child(1)"));
driver.findElement(By.xpath("//*[@id=\"s-hotsearch-wrapper\"]/div/a/div/i[1]"));
List<WebElement> li = driver.findElements(By.cssSelector("#hotsearch-content-wrapper > li > a > span.title-content-title"));
for (int i = 0;i < 6;i++) {
System.out.println(li.get(i).getText());
}
Thread.sleep(3000);
driver.quit();
}

3.2 操作测试对象
1)点击/提交对象:click()
2)模拟按键输入:sendKeys()
3)清除文本信息:clear()
4)获取对应文本:getText()
5)获取属性值:getAttribute()
6)获取当前页面标题:getTitle()
7)获取当前页面URL:getCurrentUrl()
java
void test03() throws InterruptedException {
createDriver();
// 找到输入框
WebElement input = driver.findElement(By.cssSelector("#kw"));
input.sendKeys("淘宝");
Thread.sleep(3000);
// 获取文本信息
// e.g. 第一个热搜
String txt = driver.findElement(By.cssSelector("#hotsearch-content-wrapper > li:nth-child(1) > a > span.title-content-title")).getText();
System.out.println(txt);
// 获取属性值
// e.g. "百度一下"按钮中的文本
String value = driver.findElement(By.cssSelector("#su")).getAttribute("value");
System.out.println(value);
// 清除文本信息
input.clear();
input.sendKeys("京东");
// 找到"百度一下"按钮进行点击
WebElement button = driver.findElement(By.cssSelector("#su"));
button.click();
Thread.sleep(3000);
// 获取当前页面标题
String title = driver.getTitle();
System.out.println(title);
// 获取当前页面 Url
String url = driver.getCurrentUrl();
System.out.println(url);
driver.quit();
}
3.3 窗口
1)设置窗口大小
最大化:driver.manage().window().maximize();
最小化:driver.manage().window().minimize();
全屏:driver.manage().window().fullscreen();
手动设置:driver.manage().window().setSize(new Dimension(800, 600));
java
void test04() throws InterruptedException {
createDriver();
// 窗口最大化
driver.manage().window().maximize();
Thread.sleep(1000);
// 窗口最小化
driver.manage().window().minimize();
Thread.sleep(1000);
// 全屏
driver.manage().window().fullscreen();
Thread.sleep(1000);
// 手动设置
driver.manage().window().setSize(new Dimension(800, 600));
Thread.sleep(1000);
driver.quit();
}
2)切换窗口
获取当前页面句柄:driver.getWindowHandle();
获取所有页面句柄:driver.getWindowHandles();
切换句柄:driver.switchTo().window(w);
java
void test05() throws InterruptedException {
createDriver();
// 点击百度页面的新闻
driver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
// 查看当前页面句柄
String curHandle = driver.getWindowHandle();
System.out.println(curHandle);
System.out.println("================================");
// 查看当前所有页面句柄
Set<String> allHandles = driver.getWindowHandles();
for (String handle : allHandles) {
System.out.println(handle);
// 如果句柄不一样则切换窗口
if (handle != curHandle) {
driver.switchTo().window(handle);
}
}
System.out.println("================================");
// 再次查看当前页面句柄
String curHandle2 = driver.getWindowHandle();
System.out.println(curHandle2);
// 点击新闻页面的热点要闻
driver.findElement(By.cssSelector("#headline-tabs > ul > li > a")).click();
driver.quit();
}

3)关闭窗口:driver.close();
注意:只是关闭当前标签页,窗口关闭后driver要重新定义
3.4 屏幕截图
需要先在 pom.xml 文件中添加 commons-io 依赖。
java
void test06() throws InterruptedException, IOException {
createDriver();
// 返回文件类型
File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// 放到指定位置
FileUtils.copyFile(srcFile, new File("my.png"));
driver.quit();
}

3.5 等待
1)强制等待
Thread.sleep(),参数为需要等待的时间。
优点:使用简单,调试的时候比较有效;
缺点:影响运行效率,浪费大量的时间。
2)隐式等待
driver.manage().timeouts().implicitlyWait(),参数是Duration类中提供的毫秒、秒、分钟等方法。
在等待代码后的每一行查找代码都会在指定时间内不断查找元素,如果找到则继续执行,直到超时才会报错。
优点:智能等待,作用于全局;
缺点:智能用于查找元素,且每次查找元素都要等待。
注意!由于百度网页的反爬虫/反自动化机制, 检测到了我是通过自动化工具访问,所以总是弹出滑块验证码影响测试流程,所以后面的测试都换成搜狗网页https://www.sogou.com)。

3)显式等待
在指定超时时间范围内只要满足操作的条件(不只用于查找)就会继续执行后续代码。
new WebDriverWait(driver, Duration.ofSecond(3)).until($express);
$express:涉及到selenium.support.ui.ExpectedConditions包下的ExpectedConditions类
缺点:只作用在当前条件上,其他条件想使用显式等待要重新写。

java
void test07() throws InterruptedException {
createDriver();
// 显示等待元素是否存在
//连续写法
new WebDriverWait(driver, Duration.ofSeconds(3)).until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#query")));
// 分开写法
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3));
wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#query")));
// 确保存在再进行输入
driver.findElement(By.cssSelector("#query")).sendKeys("淘宝");
// 显式等待元素是否可以点击
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#stb")));
// 确保存在且可以点击再进行点击操作
driver.findElement(By.cssSelector("#stb")).click();
driver.quit();
}
注意:混合使用隐式等待和显式等待,可能会导致不可预测的等待时间!
3.6 浏览器导航
1)打开网站
driver.navigate().to("https://baidu.com");
driver.get("https://baidu.com");
2)浏览器的前进、后退、刷新
前进:driver.navigate.forward();
后退:driver.navigate.back();
刷新:driver.navigate.refresh();
java
void test08() throws InterruptedException {
createDriver();
// 点击百科
driver.findElement(By.cssSelector("#index_baike")).click();
Thread.sleep(1000);
// 返回首页
driver.navigate().back();
Thread.sleep(1000);
// 再返回百科
driver.navigate().forward();
Thread.sleep(1000);
// 刷新百科页面
driver.navigate().refresh();
Thread.sleep(1000);
driver.quit();
}
3.7 弹窗
弹窗无法通过元素进行定位,需要先切换到弹窗上才能进行下一步操作。
Alert alert = driver.switchTo.alert();
点击确认:alert.accept();
点击取消:alert.dismiss();
输入文本信息:alert.sendKeys("hello");
警告弹窗、确认弹窗、提示弹窗
java
void test09() throws InterruptedException {
createDriver();
// 调起弹窗
driver.findElement(By.cssSelector("#alert_link")).click();
// 切换到弹窗
Alert alert = driver.switchTo().alert();
// 点击确认
alert.accept();
driver.quit();
}
3.8 文件上传
点击"上传文件"按钮后,会弹出系统的文件页面,无法使用选择器定位,所以直接将所要上传文件的路径放入sendKey中即可。
java
void test10() throws InterruptedException {
createDriver();
// 找到"选择文件"按钮
WebElement file = driver.findElement(By.cssSelector("#submit"));
// 上传想要上传文件的路径
file.sendKeys("D:\\dynamic.html");
driver.quit();
}
3.9 浏览器参数设置
1)设置无头模式:options.addArguments("-headless");
无头模式不打开浏览器,只在后台进行,工作中人工不会一直盯着执行效果,主要是通过日志来判断是否测试成功。默认是有头模式,无头模式需要手动设置。
2)设置浏览器加载策略:options.setPageLoadStrategy(PageLoadStrategy.NORMAL);
问题:手动打开页面即刻渲染,自动化打开页面加载缓慢,甚至超过等待时间直接报错,此时就需要手动设置浏览器加载策略。
| 策略 | 就绪状态 | 备注 |
|---|---|---|
| normal | complete | 默认值,等待所有资源下载 |
| eager | interactive | DOM访问已准备就绪,但诸如图像等其他资源可能仍在加载 |
| none | Any | 完全不会阻塞WebDriver |
over~