java-selenium 实战详解
selenium 作为现在最主流的UI自动化框架,基本成为了自动化测试必备的技能,本文是笔者在学习的时候做的笔记,也是实战内容。一、selenium相关配置:1、官方文档地址:https://www.selenium.dev/documentation/zh-cn/2、谷歌各版本下载http://www.chromedownloads.net/chrome64win/3、谷歌驱动下载http://
selenium 作为现在最主流的UI自动化框架,基本成为了自动化测试必备的技能,本文是笔者在学习的时候做的笔记,也是实战内容。
一、selenium相关配置:
1、官方文档地址:
https://www.selenium.dev/documentation/zh-cn/
2、谷歌各版本下载
http://www.chromedownloads.net/chrome64win/
3、谷歌驱动下载
http://npm.taobao.org/mirrors/chromedriver
4、禁止谷歌浏览器更新
https://jingyan.baidu.com/article/76a7e409f2137afc3b6e15be.html
5、selenium工作流程
● selenium client(Java等语言编写的自动化测试脚本)初始化一个service服务,通过Webdriver启动浏览器驱动程序
● 通过RemoteWebDriver向浏览器驱动程序发送HTTP请求,浏览器驱动程序解析请求,打开浏览器,并获得sessionid,如果再次对浏览器操作需携带此id
● 打开浏览器,绑定特定的端口,把启动后的浏览器作为webdriver的remote server
● 打开浏览器后,所有的selenium的操作(访问地址,查找元素等)均通过RemoteConnection链接到remote server,然后使用execute方法调用_request方法通过urlib3向remote server发送请求
● 浏览器通过请求的内容执行对应动作
● 浏览器再把执行的动作结果通过浏览器驱动程序返回给测试脚本
二、selenium的基本使用
1、添加依赖
依赖地址:https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
2、设置驱动
想要使用selenium启动浏览器必须先下载对应版本的浏览器驱动,下载后需要进行设置*
- 设置驱动有两种方式
- 设置环境变量: 将驱动设置成电脑的环境变量
- 直接在代码中声明驱动位置:
System.setProperty("webdriver.chrome.driver", "src/test/resources/chromedriver.exe");
3、打开网页
ChromeDriver chromeDriver = new ChromeDriver();
driver.get("https://www.baidu.com");
三、selenium三大等待
1、硬性等待(不推荐)
// 会一直等到设置的睡眠时间结束,造成时间浪费,一般调试用
Thread.sleep(long millis);
2、隐式等待
在设置的超时时间范围内不断查找元素,直到找到元素或者超时
如:设置等待时间为5秒,在第3秒找到元素,不再继续等待
优点:相对灵活
缺点:
设置是针对全局的,在WebDriver实例整个生命周期有效,但并不是所有的元素都需要等待。
不能适用条件更复杂的情况,如:元素可点击、元素可见
隐式等待是selenium服务器上在等待
driver.manage.timeouts().implicitlyWait(long time, TimeUnit unit);
3、显示等待
显式等待通常是我们自定义的一段代码,用来等待某个条件发生后再继续执行后续
代码(如找到元素、元素可点击、元素已显示等)
优点: 每隔一段时间500ms扫描一次页面,检查元素是否满足等待结果条件,比如查找
元素,则检查元素是否存在,不存在则继续等待,直到找到或超时。
缺点:该方式不是全局设置,因此特定需要等待的元素可以这样处理,推荐优先使用这一种方法。
显示等待是java脚本客户端在等待
// 等待元素可被点击
WebDriverWait wait = new WebDriverWait(driver,5);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[text()='官方']"))).click();
显示等待常用等待方法:
方法 | 等待条件 |
---|---|
presenceOfElementLocated | 页面元素在页面中存在 |
visibilityOfElementLocated | 页面元素在页面存在并且可见 |
elementToBeClickable | 页面元素是否在页面上可用和可被单击 |
frameToBeAvailableAndSwitchToIt | 切换到iframe中,返回值为boolean类型 |
四、元素定位
在谷歌浏览器中,可以使用F12在console中用(’#custom-bg-preview’),也可以使用 x ( x p a t h 表 达 式 ) 利 用 x p a t h 进 行 定 位 x(xpath表达式)利用xpath进行定位 x(xpath表达式)利用xpath进行定位x(’//[@title=“搜索主题、帖子、用户或分类”]’)``*`
1、css选择器
常用表达式
参考:https://www.w3school.com.cn/cssref/css_selectors.asp
选择器 | 例子 | 描述 |
---|---|---|
.class | .classStyle | 选中所有class="classStyle"的元素 |
#id | #idname | 选中所有id="idname"的元素 |
* | * | 选择所有元素 |
tagName | input | 选择所有input元素 |
ele,ele | div,input | 选择所有div和input元素 |
ele ele | div input | 选中div内所有的input元素 |
ele>ele | div>input | 选中父类有div的所有input元素 |
ele+ele | div+input | 紧接再div后面的inout元素 |
[attribute] | [name] | 选择带有name属性的所有元素 |
[attribute=value] | input[name=“x1”] | 选择name=x1的所有input元素 |
2、xPath定位
表达式 | 结果 |
---|---|
/ | 从根节点选取 |
// | 相对位置选取,不考虑当前位置 |
//* | 匹配任意节点 |
… | 父节点 |
//*[@id=‘hello’] | 选取id为hello的元素 |
/bookstore/book[1] | bookstore子元素中的第一个book元素 |
/bookstore/book[last()] | bookstore子元素中的最后一个book元素 |
/bookstore/book[last()-1] | bookstore子元素中的倒数第二个book元素 |
/bookstore/book[position() < 3] | bookstore子元素中的最前面两个book元素 |
/bookstore/book[price<30] | bookstore子元素中price大于30的所有book元素 |
3、xpath轴定位表达式:
轴名称 | 描述 |
---|---|
ancestor | 选取当前节点的所有祖先节点(包括父节点) |
parent | 选取当前节点的父节点 |
preceding | 选取当前节点之前的所有节点 |
following | 选取当前节点之后的所有节点 |
preceding-sibling | 选取当前节点之前的所有兄弟节点 |
following-sibling | 选取当前节点之后的所有兄弟节点 |
轴定位用法:
/轴名称::节点定位
//div/table//td//preceding::a[@name=‘James’]
五、按键事件(Actions)
常用事件:
按键 | 描述 |
---|---|
click | 鼠标左键单击 |
clikc_and_hold | 鼠标左键点击后不松开 |
context_click | 鼠标右键点击 |
double_click | 鼠标左键双击 |
drag_and_drop | 把元素拖拽后松开 |
move_to_element | 鼠标移动到某个元素 |
perform() | 执行按键动作 |
release | 松开鼠标左键 |
send_keys | 发送某个键到当前聚焦元素 |
key_down | 按下键盘上的某个按键 |
key_up | 松开按键 |
示例
@Test
void demo01() throws InterruptedException {
driver.get("http://sahitest.com/demo/clicks.htm");
// 创建按键对象
Actions actions = new Actions(driver);
// 单击对应按键
WebElement clickEle = driver.findElement(new By.ByXPath("//input[@value='click me']"));
actions.click(clickEle);
// 双击对应按键
WebElement doubleClickEle = driver.findElement(new By.ByXPath("//input[@value='dbl click me']"));
actions.doubleClick(doubleClickEle);
// 右键点击按键
WebElement rightClickEle = driver.findElement(new By.ByXPath("//input[@value='right click me']"));
actions.contextClick(rightClickEle);
// 执行按键操作
actions.perform();
Thread.sleep(4000);
}
@Test
void demo02() throws InterruptedException {
driver.get("http://sahitest.com/demo/dragDropMooTools.htm");
// 实现元素拖动
/*new Actions(driver).dragAndDrop(driver.findElement(new By.ById("dragger")),
driver.findElement(new By.ByXPath("//div[text()='Item 2']"))).perform();*/
// 用moveTo来实现拖动
new Actions(driver).clickAndHold(driver.findElement(new By.ById("dragger")))
.moveToElement(driver.findElement(new By.ByXPath("//div[text()='Item 2']")))
.release().perform();
Thread.sleep(3000);
}
六、多窗口和多Frame的切换
1、多窗口切换
//获取所有窗口句柄
Set<String> windowHandles = driver.getWindowHandles();
// 遍历个句柄 找到标题与目标窗口标题一致的窗口句柄
for (String windowHandle:windowHandles
) {
if(!driver.getTitle().equals("titileName")){
// 切换到目标窗口
driver.switchTo().window(windowHandle);
}
}
}
2、多Frame切换 与切换窗口类似
// 获取到frame的id或name
driver.switchTo().frame(iFrameIdOrName);
// 还可以直接获取到frame元素 进行切换
driver.switchTo().frame(frameElement);
// 如果外层没有写明的iframe 则可直接跳到ParentFrame
driver.switchTo().parentFrame(frameElement);
七、对JavaScript元素进行操作
某些特殊情况下,使用selenium的api无法操作页面元素,可以考虑通过执行js来完成。
- 使用方式1-不传参
JavascriptExecutor jsExecutor=(JavascriptExecutor) driver;
jsExecutor.executeScript("jsScript");
- 使用方式2-传参:
WebElement element = driver.findElement(By.id("xx"));
JavascriptExecutor jsExecutor=(JavascriptExecutor) driver;
jsExecutor.executeScript("arguments[0]...",element);
1、元素属性操作实例
@Test
public void test1() throws InterruptedException {
driver.get("https://www.12306.cn/index/");
WebElement timeELe = driver.findElement(By.id("train_date"));
JavascriptExecutor executor = (JavascriptExecutor) driver;
// 删除只读属性 进行手动输入日期
executor.executeScript("arguments[0].removeAttribute('readonly')",timeELe);
timeELe.clear();
timeELe.sendKeys("2020-07-18");
Thread.sleep(5000);
}
public void chooseSex(String sex) {
WebElement chooseSex;
JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
// 利用js选中性别
if (sex.equals("男")) {
chooseSex = waitElementVisible(male);
} else {
chooseSex = waitElementVisible(female);
}
jsExecutor.executeScript("arguments[0].checked=true", chooseSex);
}
2、滚动屏幕找到目标元素
页面会分为懒加载和非懒加载方式 两种方式滚动处理不同
// 从页面顶部滚动到页面底部方法
executor.executeScript("window.scrollTo(0, document.body.scrollHeight)");
executor.executeScript("window.scrollBy(0, document.body.scrollHeight)");
/**
* 懒加载 循环滚动找到目标元素
* @throws InterruptedException
*/
@Test
public void test1 () throws InterruptedException {
driver.get("https://sj.qq.com/myapp/category.htm?orgame=1");
// 懒加载页面 滚动获取页面元素
// 循环滚动页面 找到需要的元素则停止 或者到了页面底部则不再滚动
while (true){
if(driver.getPageSource().contains("抖音短视频")){
// 找到则点击该元素并退出循环
System.out.println("找到元素了");
driver.findElement(By.xpath("//a[text()='抖音短视频']")).click();
Thread.sleep(6000);
break;
}
// 没找到则继续滚动页面
// 先获取滚动页面之前的页面数据
String beforeSource = driver.getPageSource();
// 进行页面的滚动
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("window.scrollTo(0, document.body.scrollHeight)");
Thread.sleep(5000);
// 获取滚动页面后的元素
String afterSource = driver.getPageSource();
// 查看滚动前和滚动后的页面元素是否一样 一样则代表到达页面底部了 退出循环
if(beforeSource.equals(afterSource)){
System.out.println("元素未找到");
break;
}
}
}
// 非懒加载无需循环滚动可直接滚动到目标元素位置
// 滚动到目标元素
executor.executeScript("arguments[0].scrollIntoViewIfNeeded(true)", targetEle);
/**
* 非懒加载 找到指定元素
*/
@Test
public void test2() throws InterruptedException {
driver.get("https://ke.qq.com/");
WebDriverWait wait = new WebDriverWait(driver,5);
WebElement targetEle = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[text()='设计·创作']")));
JavascriptExecutor executor = (JavascriptExecutor) driver;
// 滚动到目标元素
executor.executeScript("arguments[0].scrollIntoViewIfNeeded(true)", targetEle);
Thread.sleep(6000);
}
八、文件上传
1、input元素可直接用element.sendKey()输入地址方式
WebElement ele = driver.getElement(By.id("imagUpload"));
ele.sendKey(filePath);
2、Selenium+Autolt上传文件
某些元素上传文件无法使用sendKey方式进行文件上传需要用到Autolt工具进行上传参考:https://blog.csdn.net/qq_32897143/article/details/82014603
九 弹框处理
弹框的话主要分为3中 alert、confirm确认框和Prompt,下面介绍一下三种弹框的处理
// alert对话框
public void testAlert() {
//获取alert对话框
Alert alert = driver.switchTo().alert();
//获取对话框文本
String text = alert.getText();
//打印警告对话框内容
System.out.println(text);
//alert对话框属于警告对话框,我们这里只能接受弹窗
alert.accept();
}
// confirm确认框
public void testConfirm() {
//获取confirm对话框
Alert alert = driver.switchTo().alert();
//获取对话框的内容
String text = alert.getText();
//打印对话框的内容
System.out.println(text);
//点击“确认”按钮
alert.accept();
// 点击“取消”按钮
alert.dismiss();
}
// Prompt
public void testPrompt() {
//获取prompt对话框
Alert alert = driver.switchTo().alert();
//获取对话框的内容
String text = alert.getText();
//打印对话框的内容
System.out.println(text);
//在弹框内输入信息
alert.sendKeys("软件测试");
//点击“确认”按钮,提交输入的内容
alert.accept();
}
十、除谷歌外的驱动设置
1、火狐浏览器
驱动:
https://github.com/mozilla/geckodriver/releases
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
WebDriver driver = new FirefoxDriver();
System.setProperty("webdriver.gecko.driver", "/path/to/geckodriver");
2、Edge
驱动:
https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.edge.EdgeDriver;
WebDriver driver = new EdgeDriver();
System.setProperty("webdriver.edge.driver", "C:/path/to/MicrosoftWebDriver.exe");
3、IE浏览器
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
WebDriver driver = new InternetExplorerDriver();
System.setProperty("webdriver.ie.driver", "C:/path/to/IEDriver.exe");
4、safari
● 先在终端运行
safaridriver --enable
● 允许远程自动化
/usr/bin/safaridriver -p 1337</
● 开启驱动
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.safari.SafariDriver;
WebDriver driver = new SafariDriver();
以上就是本人selenium一些基础实战内容,自动化入门的话已经足够了,当然了想要更加深入的进行UI自动化还需要学习pageObject框架、数据驱动等内容。这个后续我也会讲到
更多推荐
所有评论(0)