系列文章目录
文章目录
- 系列文章目录
- 前言
- 一、 Java版Selenium自动化测试框架介绍和原理
- 1.1 什么是Seleium
- 1.2 特点
- 1.3 注意点
- 二、安装Seleium+Chrome环境 + 创建Maven项目
- 2.1 安装Seleium + Chrome环境
- 2.2 Maven环境
- 三、Selenium4.X UI元素定位实战
- 3.1 ID选择器
- 3.2 Name选择器
- 3.3 linkText选择器
- 3.4 partialLinkText选择器
- 3.5 Class选择器
- 3.6 CSS选择器
- 3.7 TagName选择器
- 3.8 XPath选择器
- 四、 WebDriver基础操作
- 4.1 WebDriver对象API操作
- 4.2 WebElement对象API操作
- 4.3 浏览器API操作
- 4.4 鼠标事件操作
- 4.5 模拟键盘输入操作
- 4.6 显示等待和隐式等待
- 五、Selenium4.X窗口、下拉框操作
- 5.1 Selenium4.X的窗口切换实战
- 5.2 项目实战
- 5.3 Selenium4.X的快照截图
- 5.4 下拉框Select处理
- 5.5 弹窗Alert处理
- 六、Selenium4.X自动化测试多案例实战
- 6.1 UI自动化测试用例编写
- 6.2 豆瓣网自动化测试实战
前言
- Selenium是最受欢迎的Web应用程序自动化测试工具之一。
- 通过学习Selenium,可以编写自动化测试脚本,用于自动执行各种任务,例如验证功能、测试用户界面、模拟用户交互
- 大大提高测试效率,减少手动测试的工作量
一、 Java版Selenium自动化测试框架介绍和原理
1.1 什么是Seleium
Selenium自动化测试框架
-
是一个用于Web应用程序测试的自动化测试工具
-
支持多种浏览器(如Chrome、Firefox、Safari等)和操作系统(如Windows、Linux、macOS等),
-
提供了一个丰富的API,允许用户模拟真实用户的交互行为,如点击、输入、提交等
-
官网:https://www.selenium.dev
1.2 特点
- 跨平台与多浏览器支持:Selenium可以在不同的操作系统和浏览器上运行,提供了广泛的兼容性
- 开源与免费:Selenium是一个开源项目,用户可以免费地使用其中的工具和库
- 强大的API:Selenium提供了丰富的API,允许用户进行复杂的页面操作和验证
- 支持自动化测试:Selenium可以模拟真实用户的交互行为,从而进行自动化测试,提高测试效率
- 集成与扩展性:可以与其他测试工具(如Jenkins)和编程语言(如Python、Java等)集成,提供了很好的扩展性
1.3 注意点
- 环境搭建(浏览器版本和驱动版本对应关系)
- 安装Selenium库,不同语言采用不同依赖包安装
- 下载与浏览器对应的WebDriver,如ChromeDriver或GeckoDriver,并确保它们与浏览器版本匹配
- 浏览器版本一定要和驱动版本一一对应,不然存在不兼容问题
二、安装Seleium+Chrome环境 + 创建Maven项目
2.1 安装Seleium + Chrome环境
前置:环境使用的JDK21版本+Maven3.8 +IDEA旗舰版
-
驱动相关注意事项(如果驱动版本太新,可以降低版本验证)
- 浏览器版本(保证驱动版本和浏览器版本前三位相同 134.0.6998.XXX)
- 相关驱动版本下载地址(如果浏览器版本太新找不到驱动,可以降低浏览器版本,如果遇到selenium兼容性问题,统一降低版本)
- https://registry.npmmirror.com/binary.html?path=chromedriver
- https://googlechromelabs.github.io/chrome-for-testing/#stable
2.2 Maven环境
配置环境不多说,如下参考文档
手把手教你配置Maven环境并用IDEA创建一个Maven工程
- 添加依赖
<dependencies><!-- Selenium --><dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>4.10.0</version></dependency></dependencies>
添加之后爆红可以刷新加载
三、Selenium4.X UI元素定位实战
主程序入口,前置步骤,后续案例都在这里调用
public class Main {public static void main(String[] args) throws Exception {//指定驱动路径System.setProperty("webdriver.chrome.driver","D:\\developer_tools\\Broswer_Driver\\Chromedriver\\chromedriver-win64\\chromedriver.exe");// 谷歌驱动ChromeOptions options = new ChromeOptions();// 允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver = new ChromeDriver(options);//窗口最大化webDriver.manage().window().maximize();}
3.1 ID选择器
元素定位方法说明
-
在使用webdriver进行元素定位时,通常用
findElement
或findElements
方法结合By类返回元素句柄来定位元素 -
findElement() 方法返回一个元素, 如果没有找到,会抛出一个异常 NoElementFindException()
-
findElements()方法返回多个元素, 如果没有找到,会返回空数组, 不会抛出异常
-
ID元素定位
- HTML中的每个元素都可以设置一个唯一的ID属性。通过该属性 可以精确地定位到页面上的某个元素
- 在Selenium中,使用
findElement(By.id(“id的值”));
方法可以根据元素的ID进行定位
-
注意事项:
- ID应该是唯一的,因此在页面上不应该有两个或更多的元素具有相同的ID
- 如果元素的ID发生了改变,或者页面上没有该ID的元素,那么定位会失败
public static void idTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);WebElement element = webDriver.findElement(By.id("kw"));element.sendKeys("csdn");}
3.2 Name选择器
-
Name元素定位
- 在HTML中,某些元素(如
<input>
,<button>
,<select>
等)可以设置一个Name属性 - 虽然Name属性不必唯一,但在某些情况下,它可以用于定位特定的元素
- 在Selenium中,使用
findElement(By.name(“name的值”));
方法可以根据元素的Name属性进行定位
- 在HTML中,某些元素(如
-
注意事项:
- Name属性不必唯一,可能存在多个元素具有相同的Name,默认只会返回第一个匹配的元素
- 如果页面上的元素没有设置Name属性,或者Name属性的值发生了改变,那么定位会失败
public static void nameTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);WebElement element = webDriver.findElement(By.name("wd"));element.sendKeys("csdn");}
3.3 linkText选择器
Selenium4元素定位之链接方式
-
通过超链接上的文字信息来定位元素,包括通过链接的全部文字和部分文字进行定位
-
链接的全部文字定位
- 当链接的完整文本是唯一的,想要定位这个链接时,可以使用
By.linkText
方法 By.linkText("完整的链接文本")
用于查找页面上文字完全匹配的链接
- 当链接的完整文本是唯一的,想要定位这个链接时,可以使用
public static void LinkTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);WebElement element = webDriver.findElement(By.linkText("新闻"));String text = element.getText();System.out.println(text);element.click();}
3.4 partialLinkText选择器
链接的部分文字定位
- 当链接的文本不是唯一的,想基于部分文本来定位链接时,可以使用
By.partialLinkText
方法 By.partialLinkText("部分链接文本")
用于查找页面上文字包含指定文本的链接
public static void partialLinkTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);WebElement element = webDriver.findElement(By.partialLinkText("贴吧"));element.click();}
3.5 Class选择器
- Class方式
- 通过属性class定位元素,查找一个或一组显示效果相同的页面元素
driver.findElement(By.className('class属性'));
public static void classTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);List<WebElement> elements = webDriver.findElements(By.className("title-content-title"));System.out.println("size ====" + elements.size());for (WebElement element : elements) {String text = element.getText();System.out.println(text);}}
3.6 CSS选择器
Selenium4元素定位之CSS选择器方式
- selenium中的css定位,是通过css选择器来定位到具体元素,css选择器来自于css语法
- css相较与xpath选择元素:表达式更加简洁,一般情况css的运行速度是优于xpath的
- 常见的选择器包括:
- 标签:直接使用标签名,如下列:p
- 类(class):“.”(英文句号)+class值
- id:“#”+id值*
- 通配符:意为匹配所有元素, 用“*”表示
使用CSS选择器定位元素案例说明
// 通过类名定位
WebElement elementByClassName = driver.findElement(By.cssSelector(".class-name"));
// 通过ID定位(虽然通常使用By.id更直接)
WebElement elementById = driver.findElement(By.cssSelector("#element-id"));
// 通过标签名定位
WebElement elementByTagName = driver.findElement(By.cssSelector("div"));
// 通过属性定位
WebElement elementByAttribute = driver.findElement(By.cssSelector("input[name='input-name']"));
案例
public static void cssTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);List<WebElement> elements = webDriver.findElements(By.cssSelector("#s-hotsearch-wrapper > div > a.hot-title > div"));System.out.println("size ===" + elements.size());for (WebElement element : elements) {String text = element.getText();System.out.println(text);}}
3.7 TagName选择器
Selenium4元素定位之TagName选择器方式
-
标签名定位方式主要用于匹配多个页面元素的情况,将找到的页面元素对象进行计数、遍历
-
HTML的本质就是通过tag来定义实现不同的功能,每一个元素本质上也是一个tag
-
通过方法
driver.findElement(By.tagName(“标签名称”));
进行操作
public static void tarNameTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);List<WebElement> elements = webDriver.findElements(By.tagName("a"));for (WebElement element : elements) {String text = element.getText();String href = element.getAttribute("href");System.out.println(text);}}
3.8 XPath选择器
Selenium4.X元素定位之XPath案例实操**
-
什么是XPath
- XPath(XML Path Language)是一种在XML文档中查找信息的语言,也可以用于HTML
- XPath提供了非常强大的定位能力,可以定位到几乎任何元素
1.路径
1). 绝对路径:
语法:以单斜杠开头逐级开始编写,不能跳级。如:/html/body/div/p[1]/input
2). 相对路径
语法:以双斜杠开头,双斜杠后边跟元素名称,不知元素名称可以使用*代替。
如: //input 与 // *
路径结合属性
语法:在Xpath中,所有的属性必须使用@符号修饰 如://[@id=‘id值’]
路径结合逻辑(多个属性)
语法://[@id=“id值” and @属性=‘属性值’]
路径结合层级
语法://*[@id=‘父级id属性值’]/input
public static void xpathTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);List<WebElement> elements = webDriver.findElements(By.xpath("//*[@id=\"head\"]"));for (WebElement element : elements) {String text = element.getText();System.out.println(text);}}
四、 WebDriver基础操作
4.1 WebDriver对象API操作
方法 | 描述 |
---|---|
get(String url) | 访问目标 url 地址,打开网页 |
getCurrentUrl() | 获取当前页面 url 地址 |
getTitle() | 获取页面标题 |
getPageSource() | 获取页面源代码 |
close() | 关闭浏览器当前打开的窗口 |
quit() | 关闭浏览器所有的窗口 |
findElement(by) | 查找单个元素 |
findElements(by) | 查到元素列表,返回一个集合 |
getWindowHandle() | 获取当前窗口句柄 |
getWindowHandles() | 获取所有窗口的句柄 |
public static void webdriverTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);String currentUrl = webDriver.getCurrentUrl();System.out.println(currentUrl);String title = webDriver.getTitle();System.out.println("title: " + title);String pageSource = webDriver.getPageSource();System.out.println(pageSource);TimeUnit.SECONDS.sleep(2);webDriver.close();webDriver.quit();webDriver.findElement(By.id("kw")).sendKeys("csdn");Set<String> windowHandles = webDriver.getWindowHandles();for (String handle : windowHandles) {System.out.println("窗口句柄" + handle);}}
4.2 WebElement对象API操作
元素对象API操作语法
- WebElement对象常用API
方法 | 说明 |
---|---|
click | 点击对象 |
sendKeys | 在对象上模拟按键输入 |
clear | 清除对象输入的文本内容 |
submit | 提交,比如表单对象 |
getAttribute | 获取元素的指定属性 |
getText | 用于获取元素的文本信息 |
public static void webElementTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);webDriver.findElement(By.id("kw")).sendKeys("博客园");TimeUnit.SECONDS.sleep(2);webDriver.findElement(By.id("kw")).clear();TimeUnit.SECONDS.sleep(2);webDriver.findElement(By.id("kw")).sendKeys("csdn");TimeUnit.SECONDS.sleep(2);webDriver.findElement(By.id("su")).click();}
4.3 浏览器API操作
-
需求
- 浏览器操作网页,有前进、后退,不同网页直接切换,窗口最大化、刷新等
- 通过Selenium的api完成上述的操作案例
-
浏览器案例
- API语法
方法 说明 back 模拟浏览器后退按钮 forward 模拟浏览器前进按钮 refresh 刷新页面(F5) maximize 浏览器最大化 setSize 浏览器宽高 manage( ).window( ).setSize( ) 设置浏览器的大小
public static void browserTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);webDriver.findElement(By.id("kw")).sendKeys("博客园");webDriver.findElement(By.id("su")).click();TimeUnit.SECONDS.sleep(2);WebDriver.Navigation navigate = webDriver.navigate();navigate.refresh();TimeUnit.SECONDS.sleep(2);navigate.back();TimeUnit.SECONDS.sleep(2);navigate.forward();
4.4 鼠标事件操作
-
Selenium的鼠标事件
- 鼠标操作主要是通过
Actions
类来实现的,该类提供了一系列模拟鼠标操作的方法 - 包括有 右击、双击、悬停、拖动等
- 鼠标操作主要是通过
-
鼠标案例API语法
方法 说明 contextClick( ) 右击 clickAndHold( ) 鼠标点击并控制 doubleClick( ) 双击 dragAndDrop( ) 拖动 release( ) 释放鼠标 perform( ) 执行所有Actions中存储的行为
public static void mouseTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);webDriver.findElement(By.cssSelector("#kw")).sendKeys("csdn");TimeUnit.SECONDS.sleep(2);webDriver.findElement(By.cssSelector("#su")).click();TimeUnit.SECONDS.sleep(2);WebElement element = webDriver.findElement(By.cssSelector("#s_tab_inner > a.s-tab-item.s-tab-item_1CwH-.s-tab-note_2zG_i.s-tab-note > span"));TimeUnit.SECONDS.sleep(2);//鼠标右键Actions action = new Actions(webDriver);action.moveToElement(element).contextClick().perform();}
4.5 模拟键盘输入操作
什么是模拟键盘
-
利用
Actions
和Keys
类来模拟键盘操作,包括文本输入、按键和组合键序列,增强自动化脚本的用户交互能力 -
Keys
枚举提供了方便的表示键盘上按键的方法,而Actions
类则用于构建复杂的交互序列 -
这两者结合,允许在Web自动测试中模拟几乎任何类型的键盘操作
发送特殊字符
- sendKeys 使用
Keys
类中的常量,可以发送特殊字符或按键事件,sendKeys接收可变参数
sendKeys(Keys.BACK_SPACE) 回格键(BackSpace)、sendKeys(Keys.SPACE) 空格键 (Space)
sendKeys(Keys.TAB) 制表键 (Tab)、sendKeys(Keys.ESCAPE) 回退键(Esc)
sendKeys(Keys.ENTER) 回车键(Enter)、sendKeys(Keys.F1) 键盘 F1
sendKeys(Keys.CONTROL,‘a’) 全选(Ctrl+A)、sendKeys(Keys.CONTROL,‘c’) 复制(Ctrl+C)
sendKeys(Keys.CONTROL,‘x’) 剪切(Ctrl+X)、sendKeys(Keys.CONTROL,‘v’) 粘贴(Ctrl+V)
public static void keyboardTest(WebDriver webDriver) throws InterruptedException {webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);WebElement element = webDriver.findElement(By.cssSelector("#kw"));element.sendKeys("csdny");TimeUnit.SECONDS.sleep(2);//删除一个字符element.sendKeys(Keys.BACK_SPACE);TimeUnit.SECONDS.sleep(2);element.sendKeys(Keys.SPACE);element.sendKeys("博客");element.sendKeys(Keys.ENTER);}
4.6 显示等待和隐式等待
-
需求
-
Web应用通常通过异步加载(如Ajax)来动态更新页面内容,页面元素可能不是立即可用的
-
当自动化测试脚本尝试访问或操作这些元素时,如果没有等待机制,可能会遇到定位失败、元素状态不正确等异常
-
Selenium4等待主要解决以下问题:
-
元素加载延迟
- 当页面上的某些元素是通过异步请求(如Ajax)加载的,这些元素可能不会立即出现在DOM中
- 网络波动或服务器响应延迟,页面上的某些内容可能需要一些时间才能加载
- 如果没有等待机制,测试脚本可能会在元素实际可用之前访问它,导致定位失败
-
依赖关系:
- 测试脚本中的操作可能依赖于前一步的结果或内容
- 例如,一个表单提交后,可能需要等待新页面加载完成才能继续执行后续操作
-
页面更新:
-
JavaScript可能会动态更改页面内容,如添加、删除或修改元素
-
如果没有等待,测试脚本可能会错过这些变化,导致测试失败
-
-
-
-
Selenium 等待元素出现的方式有以下三种
- 强制等待
- 即线程休眠,在代码中强制当前正在执行的线程休眠(暂停执行)不管元素有没出现都固定时间
TimeUnit.SECONDS.sleep(2);
- 即线程休眠,在代码中强制当前正在执行的线程休眠(暂停执行)不管元素有没出现都固定时间
- 显式等待(Explicit Wait)
- 通俗说就是死等,不灵活的等待,在指定的时间内一定要等到某个元素的出现或可操作的状态
- 如果等不到,就一直等,直到在规定的时间之内都要操作的元素仍没找到,就抛出异常
- 可以针对特定的元素或一组元素进行等待,提供了更灵活的等待机制,可以等待复杂的条件
- 隐式等待 (Implicit Wait)
- 设置全局等待时间,全部查找都会生效,驱动初始化后就可以配置,在指定时间内轮询DOM,直到找到元素或超时
- 一旦设置,在整个WebDriver对象实例的生命周期内都有效
- 适用于等待整个页面加载完毕
- 强制等待
隐式等待案例
public static void impwaitTest(WebDriver webDriver){webDriver.get("https://www.baidu.com");//隐式等待webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));//使用一个不存在的元素idWebElement element = webDriver.findElement(By.id("sd"));element.sendKeys("csdn");}
显示等待案例
public static void waitTest(WebDriver webDriver){webDriver.get("https://www.baidu.com");//显示等待WebDriverWait wait = new WebDriverWait(webDriver, Duration.ofSeconds(10));wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("kw")));WebElement element = webDriver.findElement(By.id("kw"));element.sendKeys("csdn");}
五、Selenium4.X窗口、下拉框操作
5.1 Selenium4.X的窗口切换实战
-
需求
- 自动化测试过程中会有打开不同网页的操作
- 网页操作时会打开新窗口,不同窗口需要如何进行切换?
-
不同窗口的切换
- 自动化脚本通过识别浏览器窗口的属性用句柄handle来识别不同窗口
- 窗口句柄handle是窗口的唯一标识,是窗口的唯一ID
- 通过
webDriver.getWindowHandles()
获取窗口全部具柄 - 默认是第一个打开窗口,通过
webDriver.switchTo().window()
传入某个窗口句柄,切换到对应窗口
public static void windowTest(WebDriver webDriver)throws InterruptedException {webDriver.get("https://www.baidu.com");//隐式等待webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();//获取全部窗口的句柄Set<String> windowHandles = webDriver.getWindowHandles();String newHandle = "";for (String windowhandle : windowHandles) {System.out.println("windowhandle: " + windowhandle);//记录最后一个句柄newHandle = windowhandle;}//切换窗口 如果没调用切换 则对应的页面操作会失败webDriver.switchTo().window(newHandle);String text = webDriver.findElement(By.cssSelector("#headline-tabs > ul > li > a")).getText();System.out.println("text: " + text);}
5.2 项目实战
什么是 iframe
-
iframe
(Inline Frame)是HTML文档中的一个元素,允许在当前HTML页面中嵌入另一个HTML页面 -
其基本的用途是将另一个HTML文档嵌入到主文档中
-
就是一个网页可以嵌套到另一个网页中,可以嵌套很多层
-
使用selenium 操作浏览器时,如果需要操作iframe中的元素,首先需要切换到对应的内联框架中
- Selenium 给提供了三个重载的方法,进行操作iframe
// 方法一:通过 iframe的索引值,在页面中的位置
webDriver.switchTo().frame(index);
// 方法二:通过 iframe 的name 或者id
webDriver.switchTo().frame(nameOrId);
// 方法三:通过iframe 对应的webElement
webDriver.switchTo().frame(frameElement);
public static void iframeTest(WebDriver webDriver)throws InterruptedException {webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));webDriver.get("https://www.126.com");WebElement element = webDriver.findElement(By.xpath("//div[@class='g-bd cnt-box-include']/div[@class='g-bd']/div[@class='m-cnt']"));webDriver.switchTo().frame(element);//定位账号输入框webDriver.findElement(By.xpath("//div[@class='u-input box']/input[@name='email']")).sendKeys("lao123");webDriver.findElement(By.xpath("//div[@class='inputbox']/div[@class='u-input box']/input[@name='password']")).sendKeys("123456");}
5.3 Selenium4.X的快照截图
-
什么是Selenium的快照截图
- 自动化测试的时候,没有人工进行观看,用例执行失败如何进行发现?
- 如果遇到有错误信息等,如何保存当前页面的截图,方便后续排查?
- 快照截图功能是指Selenium自动化测试工具在测试过程中捕获浏览器窗口当前显示内容的图像
- 是Selenium在测试或调试过程中,为了保存当前浏览器窗口的可见内容而提供的一种功能
- 通常用于分析页面布局、验证页面元素的存在或状态,在测试失败时捕获页面状态以供后续分析
-
网页快照截图
- 通过API
(TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE)
- 通过API
public static void screenTest(WebDriver webDriver)throws Exception {webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));webDriver.get("https://www.baidu.com");webDriver.findElement(By.id("kw")).sendKeys("博客园");//点击搜索webDriver.findElement(By.cssSelector("#su")).click();TimeUnit.SECONDS.sleep(5);File file = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE);//存储本地String filPath = "C:\\Users\\岳不群\\Desktop\\class\\screen.png";File target = new File(filPath);//保存到本地try(FileOutputStream out = new FileOutputStream(target);FileInputStream inp = new FileInputStream(file);){byte[] buffer = new byte[1024];int total = 0;while ((total = inp.read(buffer))!=-1){out.write(buffer,0,total);}}}
5.4 下拉框Select处理
自动化测试里面的下拉框操作
-
在网页设计中,下拉框(也被称作下拉列表或者选择框)是一种用户界面控件
-
下拉框通常在被点击时显示其包含的所有选项列表,在用户选择某一选项后,列表会收回,只显示用户所选择的那个选项
-
如果一个页面元素是一个下拉框(select),对应下拉框的操作,selenium有专门的类 Select 进行处理
-
其中包含了单选和多选下拉框的各种操作,如获得所有的选项、选择某一项、取消选中某一项、是否是多选下拉框等
- 构造函数:
- Select(WebElement element): 创建一个新的 Select 对象,用于操作指定的 元素
- 选择选项的方法:
- void selectByIndex(int index): 根据索引选择选项(索引从 0 开始)
- void selectByValue(String value): 根据选项的 value 属性值选择选项
- void selectByVisibleText(String text): 根据选项的可见文本选择选项
- 取消选择选项的方法 (适用于多选下拉框):
- void deselectAll(): 取消选择所有已选中的选项
- void deselectByIndex(int index): 根据索引取消选择选项
- void deselectByValue(String value): 根据选项的 value 属性值取消选择选项
- void deselectByVisibleText(String text): 根据选项的可见文本取消选择选项
- 获取选项的方法:
- List getOptions(): 获取下拉框中的所有选项。
- List getAllSelectedOptions(): 获取下拉框中所有已选中的选项
- WebElement getFirstSelectedOption(): 获取下拉框中第一个已选中的选项
- 检查是否为多选下拉框:
- boolean isMultiple(): 返回下拉框是否支持多选
public static void selectTest(WebDriver webDriver) throws InterruptedException {webDriver.get("file:///C:/Users/%E5%B2%B3%E4%B8%8D%E7%BE%A4/Desktop/select.html");//创建一个显示等待WebDriverWait wait = new WebDriverWait(webDriver, Duration.ofSeconds(10));wait.until(ExpectedConditions.elementToBeClickable(By.id("mySelect")));//找到元素再点击WebElement element = webDriver.findElement(By.id("mySelect"));element.click();Select select = new Select(element);List<WebElement> options = select.getOptions();for (WebElement option : options) {System.out.println(option.getText());}TimeUnit.SECONDS.sleep(2);//根据选项的所见文本进行选择select.selectByVisibleText("csdn");//根据索引位置选择select.selectByIndex(1);TimeUnit.SECONDS.sleep(2);select.selectByValue("5");System.out.println(select.isMultiple());}
5.5 弹窗Alert处理
什么是Alert
- 操作alert、confirm弹出框,可以通过Alert 对象来进行操作,Alert类包含了确认、取消、输入和获取弹出窗内容。
- Alert对应属性和方法
方法 | 描述 |
---|---|
alert.getText() | 获取弹出框内容 |
alert.accept() | 接受弹窗的提示,相当于点击确认按钮 |
alert.dismiss() | 取消提示窗 |
alert.sendKeys(String s) | 给弹窗输入内容 |
网页中常用的弹出框有三种:
- alert 警告框
- confirm 确认框
- prompt 提示框
同弹窗使用流程
-
触发弹出框
- 弹出框是由页面上的某些操作触发的,比如点击一个按钮或执行某些JavaScript代码。
- 需要确保在执行下一步之前弹出框已经显示
-
切换到弹出框
- 使用
WebDriver
的switchTo().alert()
方法来切换到弹出框 - 返回一个
Alert
对象,可以通过这个对象与弹出框进行交互
- 使用
Alert alert = driver.switchTo().alert();
处理alert
弹出框:
alert
弹出框通常只包含一条消息和一个“确定”按钮,可以使用alert.accept()
方法来点击“确定”按钮
alert.accept();
处理confirm
弹出框
confirm
弹出框包含一个消息、一个“确定”按钮和一个“取消”按钮- 可以使用
alert.accept()
来点击“确定”按钮,或者使用alert.dismiss()
来点击“取消”按钮
// 点击“确定”按钮
alert.accept(); // 或者点击“取消”按钮
alert.dismiss();
public static void alertTest(WebDriver webDriver) throws InterruptedException {webDriver.get("file:///C:/Users/%E5%B2%B3%E4%B8%8D%E7%BE%A4/Desktop/select.html");//创建显示等待WebDriverWait wait = new WebDriverWait(webDriver, Duration.ofSeconds(2));wait.until(ExpectedConditions.elementToBeClickable(By.id("alert_btn"))).click();//处理alertAlert alert = webDriver.switchTo().alert();System.out.println(alert.getText());TimeUnit.SECONDS.sleep(2);alert.accept();//处理confirmwebDriver.findElement(By.id("confirm_btn")).click();//切换Alert confirm = webDriver.switchTo().alert();TimeUnit.SECONDS.sleep(2);confirm.dismiss();}
六、Selenium4.X自动化测试多案例实战
6.1 UI自动化测试用例编写
UI自动化测试用例编写规范
- 一个脚本对应一个完整场景
- 每个自动化测试脚本应覆盖一个完整的用户场景,例如从用户登录到退出系统的整个过程。
- 单一功能点验证
- 每个脚本应专注于验证一个特定的功能点,避免在一个脚本中验证多个功能。
- 正向逻辑验证为主
- 优先验证功能的正向逻辑,避免过度考虑逆向逻辑的验证,以减少脚本的复杂性和脆弱性。
- 脚本独立性
- 确保每个脚本都是独立的,不依赖于或影响其他脚本的执行。
- 数据还原
- 如果测试过程中修改了数据,测试结束后应对数据进行还原,保持测试环境的清洁。
- 验证点明确
- 在脚本中只针对明确的验证点进行验证,避免对整个脚本的每一步都进行验证。
- POM(Page Object Model)结构
- 设计遵循POM结构,将用例层、业务逻辑层和Page层明确分离。
- 页面设计规则
- 每个页面一个类,类名以Page结尾;页面辅助控件和逻辑设计为接口,并提供默认实现。
- 参数封装
- 除简单逻辑外,业务逻辑的参数使用Java Bean和枚举封装,以适应产品设计的变化。
- 状态码和文案
- 使用枚举定义状态码、产品特定文案等,以规范入参
6.2 豆瓣网自动化测试实战
-
测试用例一:用户登录功能
- 测试目标:验证用户登录功能的正确性。
- 前置条件:豆瓣网已注册用户,存在有效账号和密码。
- 测试步骤:
- 打开豆瓣网首页。
- 点击登录按钮,进入登录页面。
- 输入正确的用户名和密码。
- 点击登录按钮。
- 预期结果:
- 成功登录后,跳转到用户主页或上次访问的页面。
- 页面右上角显示登录用户的信息。
- 实际结果:记录实际登录后的页面跳转情况和用户信息显示情况。
-
测试用例二:电影搜索功能
- 测试目标:验证电影搜索功能的正确性。
- 前置条件:豆瓣网存在电影搜索功能。
- 测试步骤:
- 打开豆瓣网首页。
- 进入电影搜索页面。
- 输入电影名称或关键词。
- 点击搜索按钮。
- 预期结果:
- 搜索结果页面显示与输入关键词相关的电影列表。
- 电影列表包含电影标题、评分、导演、主演等信息。
- 实际结果:记录实际搜索结果页面的内容和展示情况。
-
测试用例三:电影评论功能
- 测试目标:验证电影评论功能的正确性。
- 前置条件:已登录豆瓣网账号,选择一部电影进入详情页面。
- 测试步骤:
- 进入电影详情页面。
- 滚动到评论区域,查看已有评论。
- 点击写评论按钮,输入评论内容。
- 点击提交按钮。
- 预期结果:
- 评论成功提交后,在页面上能够看到新添加的评论。
- 新评论包含评论者头像、昵称、评论内容、时间等信息。
- 实际结果:记录评论提交后的页面显示情况和新评论的展示情况。
-
测试用例四:豆瓣读书模块功能
- 测试目标:验证豆瓣读书模块功能的正确性。
- 前置条件:豆瓣网存在读书模块,包含书籍搜索、书籍详情、书评等功能。
- 测试步骤(以书籍搜索为例):
- 进入豆瓣读书页面。
- 在搜索框中输入书籍名称或关键词。
- 点击搜索按钮。
- 预期结果:
- 搜索结果页面显示与输入关键词相关的书籍列表。
- 书籍列表包含书籍封面、标题、作者、评分等信息。
- 实际结果:记录实际搜索结果页面的内容和展示情况。
-
测试用例五:豆瓣同城活动功能
- 测试目标:验证豆瓣同城活动功能的正确性。
- 前置条件:豆瓣网存在同城活动模块,包含活动搜索、活动详情、报名等功能。
- 测试步骤(以活动搜索为例):
- 进入豆瓣同城页面。
- 在搜索框中输入活动类型或关键词。
- 点击搜索按钮。
- 预期结果:
- 搜索结果页面显示与输入关键词相关的活动列表。
- 活动列表包含活动名称、时间、地点、参与人数等信息。
- 实际结果:记录实际搜索结果页面的内容和展示情况。
组件代码封装
package net.xdclass;import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;public class SeleiumBase {protected WebDriver webDriver;//初始化方法public void setUp() {//指定驱动路径System.setProperty("webdriver.chrome.driver","D:\\developer_tools\\Broswer_Driver\\Chromedriver\\chromedriver-win64\\chromedriver.exe");// 谷歌驱动ChromeOptions options = new ChromeOptions();// 允许所有请求options.addArguments("--remote-allow-origins=*");webDriver = new ChromeDriver(options);webDriver.manage().window().maximize();}/*** 退出浏览器*/public void tearDown() {if (webDriver != null) {webDriver.quit();}}
}
用例编写
package net.xdclass;import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;import java.time.Duration;public class TestReadBookPage extends SeleiumBase{/*** 在所有测试执行前进行初始化操作。* 初始化浏览器驱动,设置隐式等待时间,并导航到豆瓣首页。*/@BeforeClasspublic void setupClass(){setUp();webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));webDriver.get("https://www.douban.com/");}/*** 在所有测试执行后进行清理操作。* 主要是为了调用父类的清理方法,确保资源正确释放。*/@AfterClasspublic void tearDownClass(){tearDown();}/*** 测试豆瓣首页的标题是否包含"豆瓣"。* 该测试优先级为1,确保在其他测试之前执行。*/@Test(priority=1)public void testHomePageTitle(){String title = webDriver.getTitle();System.out.println(title);Assert.assertTrue(title.contains("豆瓣"),"标题不包括豆瓣");}/*** 从首页点击进入读书页面,验证是否成功进入豆瓣读书页面。* 该测试依赖于testHomePageTitle测试,只有在首页标题测试通过后才会执行。*/@Test(priority=2)public void testEnterBookPage(){webDriver.findElement(By.xpath("//*[@id=\"anony-nav\"]/div[1]/ul/li[1]/a")).click();//切换窗口webDriver.getWindowHandles().forEach(window -> webDriver.switchTo().window(window));String currentUrl = webDriver.getCurrentUrl();System.out.println("currentUrl: " + currentUrl);Assert.assertTrue(currentUrl.contains("book.douban.com"), "没有进入到豆瓣读书页面");}/*** 测试搜索功能,搜索关键词"斗破苍穹",验证是否进入搜索结果页面。* 该测试优先级为3,旨在测试搜索功能的基本可用性。*/@Test(priority=3)public void testSerarchPage(){webDriver.findElement(By.id("inp-query")).sendKeys("斗破苍穹");webDriver.findElement(By.xpath("//*[@id=\"db-nav-book\"]/div[1]/div/div[2]/form/fieldset/div[2]/input")).click();String title = webDriver.getTitle();System.out.println(title);Assert.assertTrue(title.contains("斗破苍穹"),AssertMessage.ERROR_TITLE_MESSAGE);}/*** 验证搜索结果中是否包含"斗破苍穹"这本书。* 该测试依赖于testSearchPage,确保搜索功能正常后验证搜索结果。*/@Test(priority=4)public void testSearchResult(){WebElement element = webDriver.findElement(By.xpath("//*[@id=\"root\"]/div/div[2]/div[1]/div[1]/div[3]/div/div/div[1]"));String text = element.getText();Assert.assertTrue(text.contains("斗破苍穹"),"标题不对");}
}