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 =newChromeDriver();
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 =newWebDriverWait(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"的元素**选择所有元素tagNameinput选择所有input元素ele,elediv,input选择所有div和input元素ele elediv input选中div内所有的input元素ele>elediv>input选中父类有div的所有input元素ele+elediv+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松开按键
示例
@Testvoiddemo01()throwsInterruptedException{
driver.get("http://sahitest.com/demo/clicks.htm");// 创建按键对象Actions actions =newActions(driver);// 单击对应按键WebElement clickEle = driver.findElement(newBy.ByXPath("//input[@value='click me']"));
actions.click(clickEle);// 双击对应按键WebElement doubleClickEle = driver.findElement(newBy.ByXPath("//input[@value='dbl click me']"));
actions.doubleClick(doubleClickEle);// 右键点击按键WebElement rightClickEle = driver.findElement(newBy.ByXPath("//input[@value='right click me']"));
actions.contextClick(rightClickEle);// 执行按键操作
actions.perform();Thread.sleep(4000);}@Testvoiddemo02()throwsInterruptedException{
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来实现拖动newActions(driver).clickAndHold(driver.findElement(newBy.ById("dragger"))).moveToElement(driver.findElement(newBy.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、元素属性操作实例
@Testpublicvoidtest1()throwsInterruptedException{
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);}publicvoidchooseSex(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
*/@Testpublicvoid test1 ()throwsInterruptedException{
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);/**
* 非懒加载 找到指定元素
*/@Testpublicvoidtest2()throwsInterruptedException{
driver.get("https://ke.qq.com/");WebDriverWait wait =newWebDriverWait(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对话框publicvoidtestAlert(){//获取alert对话框Alert alert = driver.switchTo().alert();//获取对话框文本String text = alert.getText();//打印警告对话框内容System.out.println(text);//alert对话框属于警告对话框,我们这里只能接受弹窗
alert.accept();}// confirm确认框publicvoidtestConfirm(){//获取confirm对话框Alert alert = driver.switchTo().alert();//获取对话框的内容String text = alert.getText();//打印对话框的内容System.out.println(text);//点击“确认”按钮
alert.accept();// 点击“取消”按钮
alert.dismiss();}// PromptpublicvoidtestPrompt(){//获取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 =newFirefoxDriver();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 =newEdgeDriver();System.setProperty("webdriver.edge.driver","C:/path/to/MicrosoftWebDriver.exe");
3、IE浏览器
importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.ie.InternetExplorerDriver;WebDriver driver =newInternetExplorerDriver();System.setProperty("webdriver.ie.driver","C:/path/to/IEDriver.exe");
4、safari
● 先在终端运行
safaridriver --enable
● 允许远程自动化
/usr/bin/safaridriver -p 1337</
● 开启驱动
importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.safari.SafariDriver;WebDriver driver =newSafariDriver();
以上就是本人selenium一些基础实战内容,自动化入门的话已经足够了,当然了想要更加深入的进行UI自动化还需要学习pageObject框架、数据驱动等内容。这个后续我也会讲到
版权归原作者 小测. 所有, 如有侵权,请联系我们删除。