WebUI自动化知识点总结-基于Java语言
一:Selenium简介
Selenium用于Web应用程序测试的工具,开源并且免费的,覆盖IE、Chrome、FireFox、Safari等主流浏览器,通过在不同浏览器中运行自动化测试。支持Java、Python、Net、Perl等编程语言进行自动化测试脚本编写。
Selenium家族:
- Selenium IDE,Firefox/Chrome浏览器的扩展插件,通过Selenium IDE我们可以录制和回放浏览器操作,快速实现自动化测试,功能很鸡肋,很难扩展自定义功能,一般很少用。
- Selenium WebDriver,Selenium的核心,提供了各种语言环境的API来支持更多控制权和编写符合标准软件开发实践的应用程序。
- Selenium Grid,分布式测试,通过Selenium Grid可以将自动化测试脚本分发到不同的测试机器中执行。
二:驱动的使用:
1、浏览器驱动下载地址:

2、设置驱动文件路径:
DesiredCapabilities capabilities = new DesiredCapabilities();
//取消IE安全设置(忽略IE的Protected Mode的设置)
capabilities.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
//忽略浏览器缩放设置
capabilities.setCapability(InternetExplorerDriver.IGNORE_ZOOM_SETTING, true);
System.setProperty("webdriver.ie.driver", "src\\test\\resources\\IEDriverServer.exe");
WebDriver webDriver = new InternetExplorerDriver(capabilities);
3、驱动的执行原理:

三:元素定位
1、ID定位
如果页面存在ID唯一定位到的元素,可以优先考虑使用id定位,如:百度的输入框定位:By.id("kw")

2、name定位
3、tagName定位:
4、className定位
5、linkText定位
6、partialLinkText 定位
7、cssSelector定位
8、XPATH定位
轴名称 | 释义 |
---|---|
ancestor | 选取当前节点的所有祖先节点(包括父节点) |
parent | 选取当前节点的父节点 |
preceding | 选取当前节点之前的所有节点 |
preceding-sibling | 选取当前节点之前的所有兄弟节点 |
following | 选取当前节点之后的所有节点 |
following-sibling | 选取当前节点之后的所有兄弟节点 |
使用方式:轴名称::标签名
示例:取百度搜索框的父元素span标签元素: //input[@id='kw']//parent::span
取百度搜索框之前的兄弟元素span标签元素://input[@id='kw']//preceding::span[@class='soutu-btn']
四:selenium常用操作 API
1、元素对象常用API
首先先有元素对象:Webelement element=driver.findElement(By by);其中by是元素定位信息
(1.1)、点击操作:element.click();
(1.2)、输入内容:element.sendKeys("str");
(1.3)、清除内容:element.clear();
(1.4)、键盘操作:
(1.4.1)element.sendKeys(Keys.CONTROL,"a");//ctrl+a 全选
(1.4.2)element.sendKeys(Keys.CONTROL,"x");//ctrl+x 剪切
(1.4.3)element.sendKeys(Keys.CONTROL,"c");//ctrl+c 复制
(1.4.4)element.sendKeys(Keys.CONTROL,"v");//ctrl+v 粘贴
(1.4.5)element.sendKeys(Keys.ENTER);//回车
(1.4.6)element.sendKeys(Keys.BACK_SPACE);//删除
(1.4.7)element.sendKeys(Keys.SPACE);//空格键
(1.5)、获取元素标签名:element.getTagName();
(1.6)、获取元素属性:element.getAttribute();
(1.7)、获取元素文本值:element.getText();
2、driver对象常用API
(2.1)、访问指定url:driver.get("url")
(2.2)、获取当前页面url:driver.getCurrentUrl();
(2.3)、获取当前页面标题:driver.getTittle();
(2.4)、获取当前页面源码:driver.getPageSource();
(2.5)、关闭driver当前所在窗口:driver.close();
(2.6)、关闭driver对象以及所有窗口:driver.quit()
(2.7.2)、浏览器全屏:window.fullscreen();
File file=driver.getScreenshotAs(OutputType FILE);
try{
FileUtils.copyFile(file,new File("E:\\projectDir"));
}catch(IOException e){
e.printStackTrace();
}
五:三种等待:硬等待、隐式等待、显式等待
1、硬等待:Thread.sleep(long millis)
特点:强制线程等待
优点:使用简单
缺点:容易造成时间浪费,建议少用
2、隐式等待:driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
特点:在设置的超时时间范围内不断查找元素,直到找到元素或者超时为止
优点:只需要设置一次,在 WebDriver 实例的整个生命周期都是生效的
缺点:只能找到元素,不能适用条件更复杂的情况,如:元素可点击、元素可见、元素的属性发生变化等。
3、显示等待:
特点:可以灵活指定等待到元素满足某个条件为止,最常用
优点:基本可以满足所有元素等待条件,使得自动化脚本更加稳定
缺点:暂无缺点
使用方法:先创建一个WebDriverWait对象: WebDriverWait webDriverwait=new WebDriverWait();
//等待元素可点击
webDriverWait.until(ExpectedConditions.elementToBeClickable(By));
//等待元素可见,光是找到元素不行,必须得能被看到
webDriverWait.until(ExpectedConditions.visibilityOfElementLocated(By));
//等待元素找到
webDriverWait.until(ExpectedConditions.presenceOfElementLocated(By));
//等待所有元素可见
webDriverWait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By));
(1)封装等待元素可见方法:
/**
* 显式等待元素可见二次封装
* @param driver 驱动对象
* @param by 元素定位信息
*/
public WebElement waitElementVisible(RemoteWebDriver driver, By by ){
WebElement webElement = null;
try {
//1、实例化WebDriverWait 超时时间10s
WebDriverWait webDriverWait = new WebDriverWait(driver,10);
//2、通过until方法等到某个条件满足时为止
webElement = webDriverWait.until(ExpectedConditions.visibilityOfElementLocated(by));
}catch (Exception e){
e.printStackTrace();
}
return webElement;
}
(2)封装元素可被点击方法:
/**
* 显式等待元素可被点击二次封装
* @param driver 驱动对象
* @param by 元素定位信息
*/
public WebElement waitElementClickable(RemoteWebDriver driver, By by ){
WebElement webElement =null;
try {
//1、实例化WebDriverWait 超时时间10s
WebDriverWait webDriverWait = new WebDriverWait(driver, 10);
//2、通过until方法等到某个条件满足时为止
webElement = webDriverWait.until(ExpectedConditions.elementToBeClickable(by));
}catch (Exception e){
e.printStackTrace();
}
return webElement;
}
六:三种切换
1、切换windows
当我们点击a标签元素时,如果a标签有target="_blank"
时,就会打开一个新的窗口,这时候我们如果想要操作新窗口的元素,需要切换windows。
/**
* 封装的通用切换窗口的方法-根据对应窗口的标题来切换
* @param title 窗口标题
*/
public void switchWindowWithTitle(String title){
Set<String> allWindowHandles = driver.getWindowHandles();
for (String windowHandle: allWindowHandles){
//根据窗口的标题来进行判断
if(title.equals(driver.getTitle())){
break;
}else {
logger.info("切换到标题为:【"+title+"】的窗口");
driver.switchTo().window(windowHandle);
}
}
}
/**
* 封装的通用切换窗口的方法-根据对应窗口的url来切换
* @param url 窗口url
*/
public void switchWindowWithURL(String url){
Set<String> allWindowHandles = driver.getWindowHandles();
for (String windowHandle: allWindowHandles){
//根据窗口的URL来进行判断
if (url.equals(driver.getCurrentUrl())){
break;
}else {
logger.info("切换到url为:【"+url+"】的窗口");
driver.switchTo().window(windowHandle);
}
}
}
2、切换Iframe
当想要定位iframe中的元素时,我们需要切换Iframe,否则无法定位Iframe里的元素
/**
* 切换到指定IFrame封装
* @param driver 驱动对象
* @param by 元素定位信息
* @param frameInfo 自定义frame信息
*/
public void switchFrame(RemoteWebDriver driver,By by,String frameInfo){
WebElement element = waitElementVisible(driver, by);
logger.info("切换IFrame:"+frameInfo);
driver.switchTo().frame(element);
}
/**
* 从IFrame中切换到默认页面封装
* @param driver 驱动对象
*/
public void switchDefaultFrame(RemoteWebDriver driver){
logger.info("切换回默认的页面");
driver.switchTo().defaultContent();
}
3、切换Alert弹窗
有些时候,由浏览器弹出一个Alert提示框,如果我们不去处理,无法进行下一步操作。
/**
* Alert弹窗切换
* @param driver 驱动对象
*/
public void switchAlert(RemoteWebDriver driver){
logger.info("切换到alert窗口");
Alert alert = driver.switchTo().alert();
// alert.accept(); //点击确定
//alert.dismiss(); //点击取消
alert.getText(); //获取弹窗文本
}
七:特殊元素操作
1、JavaScript操作
某些特殊情况下,使用selenium的api无法操作页面元素,或者运行的时候报元素无法被点击等异常错误时,这时候可以考虑通过JavaScript操作是否能解决问题。
使用方式:
(1)不传参方式:
driver.executeScript("JS代码");
(2)传参方式:
WebElement element = driver.findElement(By.id("xx"));
driver.executeScript("arguments[0].click();",element);
使用场景:(1)设置/去除元素属性:setAttribute()/removeAttribute(),这里以12306网站为例:
driver.get("https://www.12306.cn/index/");
Thread.sleep(2000);
//设置元素的属性值
driver.executeScript("document.getElementById('train_date').setAttribute('value','2020-1-1');");
//移除掉元素的属性值
driver.executeScript("document.getElementById('train_date').removeAttribute('value');");
(2)页面滚动
实例1:12306网站操作:
driver.get("https://www.12306.cn/index/");
Thread.sleep(2000);
//滚动到页面底部
//driver.executeScript("window.scrollTo(0, document.body.scrollHeight);");
//2-2、滚动到指定的元素上去
driver.executeScript("document.getElementById('index_ads').scrollIntoViewIfNeeded(true);");
实例2:在豌豆荚软件排行页面"https://www.wandoujia.com/top/app"不断地滚动对【虎牙直播】元素点击。
ublic class UITest04 {
public static void main(String[] args) throws InterruptedException {
RemoteWebDriver driver = getDriver("chrome");
driver.get("https://www.wandoujia.com/top/app");
driver.manage().window().maximize();
Thread.sleep(1000);
while (true){
if (driver.getPageSource().contains("title=\"虎牙直播\"")) {
driver.findElementByXPath("//a[text()='虎牙直播']").click();
break;
}else {
//点击查看更多
WebElement loadMore = waitElementVisible(driver, By.xpath("//div[@class='load-more']/a"));
//判断【查看更多】是否已经加载完,如果加载完,则跳出循环
if (loadMore.getAttribute("style").equals("display: none;")){
break;
}
driver.executeScript("arguments[0].scrollIntoViewIfNeeded(true);", loadMore);
loadMore.click();
Thread.sleep(1000);
}
}
Thread.sleep(1000);
driver.quit();
}
/**
* 封装的通用切换窗口的方法-根据对应窗口的标题来切换
* @param driver 驱动对象
* @param title 窗口标题
*/
public static void switchWindow(WebDriver driver, String title) {
Set<String> allWindowHandles = driver.getWindowHandles();
for (String windowHandle: allWindowHandles){
//根据窗口的URL地址或者标题来进行判断
if(title.equals(driver.getTitle())){
break;
}else {
driver.switchTo().window(windowHandle);
}
}
}
/**
* 显式等待元素可见二次封装
* @param driver
* @param by
*/
public static WebElement waitElementVisible(WebDriver driver, By by ){
//1、实例化WebDriverWait 超时时间10s
WebDriverWait webDriverWait = new WebDriverWait(driver,10);
//2、通过until方法等到某个条件满足时为止
WebElement webElement = webDriverWait.until(ExpectedConditions.visibilityOfElementLocated(by));
return webElement;
}
/**
* 显式等待元素可被点击二次封装
* @param driver
* @param by
*/
public static WebElement waitElementClickable(WebDriver driver, By by ){
//1、实例化WebDriverWait 超时时间10s
WebDriverWait webDriverWait = new WebDriverWait(driver,10);
//2、通过until方法等到某个条件满足时为止
WebElement webElement = webDriverWait.until(ExpectedConditions.elementToBeClickable(by));
return webElement;
}
/**
* 打开所有浏览器封装
* @param type 浏览器类型
* @return
*/
public static RemoteWebDriver getDriver(String type){
RemoteWebDriver driver = null;
if("chrome".equals(type)){
//1、加载浏览器驱动
System.setProperty("webdriver.chrome.driver","src/test/resources/chromedriver.exe");
//2、创建ChromeDriver对象
driver =new ChromeDriver();
}else if ("firefox".equals(type)){
//加载浏览器驱动
System.setProperty("webdriver.gecko.driver","src/test/resources/geckodriver.exe");
//如果firefox不是默认路径,配置firefox路径
System.setProperty("webdriver.firefox.bin","D:\\Program Files\\Mozilla Firefox\\firefox.exe");
driver=new FirefoxDriver();
}else if ("ie".equals(type)){
//加载浏览器驱动
System.setProperty("webdriver.ie.driver","src/test/resources/IEDriverServer.exe");
//IE浏览器默认会有125%的缩放和安全设置,需要禁用,不然会报错
DesiredCapabilities capabilities=new DesiredCapabilities();
capabilities.setCapability(InternetExplorerDriver.IGNORE_ZOOM_SETTING,true); //忽略浏览器缩放比例
capabilities.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS,true);//忽略IE浏览器的安全模式
//创建IEDriver
driver=new InternetExplorerDriver();
}else {
System.out.println("浏览器传值有误");
}
return driver;
}
}
(3)执行的时候,控制台报错如下:Element is not clickable at point,Other element would receive the click ,或者其他奇形怪状的错误的时候,都可以考虑使用JavaScript操作尝试下是否能解决错误。
2、鼠标操作
自动化有些场景是需要鼠标配合使用的时候,可以使用Selenium的Actions类来模拟鼠标操作,通过Actions对象可以发起鼠标左键、右键、移动鼠标等操作,最后使用perform方法执行操作。
clickAndHold(element) //在特定元素上单击鼠标左键(不释放)
release(element) //在特定元素上释放鼠标左键
doubleClick(element) //在特定元素上双击鼠标左键
moveToElement(element) //移动鼠标指针到特定元素
contextClick(element) //在特定元素上右键单击
dragAndDrop(element) //拖拽元素
perform() //执行具体的操作,前面6个方法都是声明一个操作,只有调用perform()后才会真正执行操作
使用方式:
Actions actions = new Actions(driver);
WebElement webElement1 = driver.findElement(By.id("XX"));
WebElement webElement2 = driver.findElement(By.id("XX"));
//按住-->拖拽-->鼠标释放
actions.clickAndHold(webElement1).moveToElement(webElement2).release().perform();
//双击
actions.doubleClick(webElement1).perform();
3、文件上传操作
参考:http://testingpai.com/article/1595507303689
4:验证码操作
(1)、与开发沟通在测试环境去除验证码
(2)、在测试环境开个万能验证码,推荐使用
(3)、使用自动识别技术破解验证码,时间充裕可以尝试
(4)、通过读取Redis缓存,绕过验证码。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了