当前位置: 首页 > news >正文

【JUnit实战3_26】第十五章:表现层测试(下)—— Selenium 在网页测试中的用法

JUnit in Action, Third Edition

《JUnit in Action》全新第3版封面截图

写在前面
本篇继续介绍表现层测试,用到的测试工具为 SeleniumSelenium 发展到今天就像微软的 Excel 一样在自动化测试领域可谓无处不在了,本章不可能一一演示 Selenium 的每个应用场景,只能蜻蜓点水简单应用一下,适合测试新手;这篇笔记只是从实战出发,对书中给出的案例进行实操、复盘,只能从宏观上了解 Selenium 的用法,想要深耕甚至精通这个工具还有很长一段路要走。

(接上篇)

15.4 Selenium 简介

Selenium(https://www.selenium.dev/)是一套免费开源的 Web 应用测试工具集。它与 HtmlUnit 在相同虚拟机中模拟浏览器来运行测试的方式不同,Selenium 的优势在于能够在特定操作系统上针对真实浏览器运行测试。

Selenium WebDriver 是编写测试时要用到的核心接口。作为 W3C 的推荐标准,当前的主流浏览器均实现了该接口。WebDriver 利用这些浏览器对自动化的原生支持,可以直接向浏览器发起调用,从而实现表现层的自动化测试。

Selenium WebDriver 的架构示意图如下:

Fig15.6

WebDriver 包含四个组件:

  • Selenium 客户端库:即编写测试用例需要的 Selenium 库,支持多种编程语言(JavaC#PHPPythonRuby 等);
  • 基于 HTTPJSON 有线协议:每个 WebDriver 都有自己的 HTTP 服务器。该协议是一种通过 HTTP 服务器传递信息的 REST API
  • 浏览器驱动:每个浏览器都有独立的驱动程序(driver),用于与对应的浏览器进行通信,同时又不暴露浏览器功能的内部逻辑;当浏览器驱动接到命令时,该命令会在对应的浏览器上执行,并以 HTTP 响应的形式返回结果。
  • 浏览器:即 Selenium 兼容的浏览器,如 ChromeFirefoxEdgeSafari 等。

常见的浏览器及其对应驱动梳理:

Web 浏览器浏览器驱动类
Google ChromeChromeDriver
Internet ExplorerInternetExplorerDriver
SafariSafariDriver
OperaOperaDriver
FirefoxFirefoxDriver
EdgeEdgeDriver

15.5 Selenium 用法演示

实战准备工作:

  • 分别下载 ChromeFirefoxEdgeWeb 驱动(必须与本机浏览器版本一致)——
    • ChromeDriver:win64 zip(本机 Chrome 版本:v142.0.7444.60
    • FirefoxDriver:geckodriver-v0.36.0-win64.zip(本机 Firefox 版本:v144.0.2 (64-bit)
    • EdgeDriver:edgedriver_win64.zip(本机 Edge 版本:v142.0.3595.53
  • 将上述压缩包内的驱动程序统一解压到 D:/manning/drivers/ 文件夹下,并将该路径配置到环境变量 PATH 中。

测试环境变量是否生效(均已生效):

> msedgedriver --version
Microsoft Edge WebDriver 142.0.3595.53 (e9d637e9672ec1e9386e16d27f47c1384f2bae93)
> chromedriver --version
ChromeDriver 142.0.7444.59 (4b8153ab58d3c3f4c9f7e4baad9616ecf80db5fa-refs/branch-heads/7444_52@{#4})
> geckodriver --version
geckodriver 0.36.0 (a3d508507022 2025-02-24 15:57 +0000)

15.5.1 示例1:对特定 Web 浏览器进行测试

public class ChromeSeleniumTest {private WebDriver driver;@BeforeEachvoid setUp() {driver = new ChromeDriver();}@Testvoid testChromeManning() {driver.get("https://www.manning.com/");assertThat(driver.getTitle(), is("Manning"));}@Testvoid testChromeGoogle() {driver.get("https://www.google.com");assertThat(driver.getTitle(), is("Google"));}@AfterEachvoid tearDown() {driver.quit();}
}

注意:实测过程中会弹出一个新的浏览器窗口加载网页(即 Chrome 驱动程序),稍后自动关闭:

Fig15.8

最终实测效果:

Fig15.7

15.5.2 示例2:使用 Web 浏览器测试导航

实测用 Firefox 驱动访问维基百科首页,并从捐赠链接打开捐赠页面,判定页面标题是否一致(原 Content 内容链接早已改版,以下代码根据最新页面修改):

public class WikipediaAccessTest {private RemoteWebDriver driver;@BeforeEachvoid setUp() {driver = new FirefoxDriver();}@Testvoid testWikipediaAccess() {driver.get("https://en.wikipedia.org/");assertThat(driver.getTitle(), is("Wikipedia, the free encyclopedia"));WebElement contents = driver.findElement(By.linkText("Donate"));assertTrue(contents.isDisplayed());contents.click();assertThat(driver.getTitle(), is("Make your donation now - Wikimedia Foundation"));}@AfterEachvoid tearDown() {driver.quit();}
}

实测效果(中途 Firefox 驱动程序窗口会自动打开 Wiki 首页,然后自动跳转到 Donate 页面):

Fig15.10

Fig15.9

15.5.3 示例3:测试多个 Web 浏览器

利用 JUnit 5 的参数化测试注解及相关写法,还可以批量注入不同的浏览器 driver 实例,一次性执行多个测试:

public class MultiBrowserSeleniumTest {private WebDriver driver;public static Collection<WebDriver> getBrowserVersions() {return Arrays.asList(new WebDriver[]{ new FirefoxDriver(), new ChromeDriver() });}@ParameterizedTest@MethodSource("getBrowserVersions")void testManningAccess(WebDriver driver) {this.driver = driver;driver.get("https://www.manning.com/");assertThat(driver.getTitle(), is("Manning"));}@ParameterizedTest@MethodSource("getBrowserVersions")void testGoogleAccess(WebDriver driver) {this.driver = driver;driver.get("https://www.google.com");assertThat(driver.getTitle(), is("Google"));}@AfterEachvoid tearDown() {driver.quit();}
}

实测时发现 Edge 驱动程序存在很多问题:先提示系统变量 webdriver.edge.driver 缺失,通过静态代码块手动补全后又报该框架没有执行上下文。后者尝试过升级 Selenium 版本、新增 Driver Manager 依赖、提问 DeepSeek 修改测试逻辑等方法,均以失败告终:

Fig15.12

剔除 Edge 驱动后,最终运行结果:

Fig15.11

15.5.4 示例4:用不同的 Web 浏览器测试 Google 搜索和导航

本节案例通过对 ChromeFirefox 驱动进行参数化测试,实测其通过谷歌检索维基百科,并点击第一个词条进入其首页,然后点开其 Donate 捐赠页面完成相应测试逻辑。实测代码如下(已调整):

public class GoogleSearchTest {private RemoteWebDriver driver;public static Collection<RemoteWebDriver> getBrowserVersions() {return Arrays.asList(new RemoteWebDriver[]{new ChromeDriver(), new FirefoxDriver()});}@ParameterizedTest@MethodSource("getBrowserVersions")void testGoogleSearch(RemoteWebDriver driver) {this.driver = driver;driver.get("http://www.google.com");WebElement element = driver.findElement(By.name("q"));element.sendKeys("en.wikipedia.org");driver.findElement(By.name("q")).sendKeys(Keys.ENTER);// wait until the Google page shows the resultWebElement myDynamicElement = (new WebDriverWait(driver, 100)).until(ExpectedConditions.presenceOfElementLocated(By.id("result-stats")));List<WebElement> findElements = driver.findElements(By.xpath("//*[@id='rso']//a/h3"));findElements.get(0).click();assertEquals("https://en.wikipedia.org/wiki/Main_Page", driver.getCurrentUrl());assertThat(driver.getTitle(), is("Wikipedia, the free encyclopedia"));WebElement contents = driver.findElement(By.linkText("Donate"));assertTrue(contents.isDisplayed());contents.click();assertThat(driver.getTitle(), is("Make your donation now - Wikimedia Foundation"));}@AfterEachvoid tearDown() {driver.quit();}
}

和之前不同的是,频繁调用测试可能触发谷歌的人机检测模块,需要手动验证一下。其余流程均自动进行:

Fig15.13

最终效果:

Fig15.14

15.5.5 示例5:测试网站的身份验证

本例模拟了在浏览器打开指定页面后,再从当前页面点开一个登录页,并自动完成帐号信息的填写(一次正确+一次错误):

public class LoginTest {private Homepage homepage;private WebDriver webDriver;public static Collection<WebDriver> getBrowserVersions() {return Arrays.asList(new WebDriver[]{new FirefoxDriver(), new ChromeDriver()});}@ParameterizedTest@MethodSource("getBrowserVersions")public void loginWithValidCredentials(WebDriver webDriver) {this.webDriver = webDriver;homepage = new Homepage(webDriver);homepage.openFormAuthentication().loginWith("tomsmith", "SuperSecretPassword!").thenLoginSuccessful();}@ParameterizedTest@MethodSource("getBrowserVersions")public void loginWithInvalidCredentials(WebDriver webDriver) {this.webDriver = webDriver;homepage = new Homepage(webDriver);homepage.openFormAuthentication().loginWith("tomsmith", "SuperSecretPassword").thenLoginUnsuccessful();}@AfterEachvoid tearDown() {webDriver.quit();}
}

以下是实测过程中的自动填写表单时的动态截图:

Fig15.15

最终执行结果:

Fig15.16

注意

本章没有详细讨论 HtmlUnitSelenium 爬取网页元素及内容的具体 API 写法,因为它们很可能随着版本的升级而不断改进。因此学习本章时重点在于把握大的操作流程和粗粒度的底层逻辑,实际工作中遇到类似场景再深入挖掘相关接口。

http://www.dtcms.com/a/564577.html

相关文章:

  • 浏览器——CSDN网站的页面就是打不开,显示无法访问的解决办法
  • 110、23种设计模式之状态模式(19/23)
  • 做一手楼盘的网站嵌入式工程师能干多久
  • Spring Boot 应用 Docker 监控:Prometheus + Grafana 全方位监控
  • git clone失败
  • Linux 命令与运维终极手册(2025 完整版)
  • 05-异常处理-导读
  • Pandas-之 数据聚合与分组
  • Rust之基础入门项目实战:构建一个简单的猜谜游戏
  • 数据结构之二叉树-初见介绍
  • 【Java 开发日记】finally 释放的是什么资源?
  • VsCode中终端无法运行前端命令
  • 【鸿蒙开发】鸿蒙 ArkTS 语言从零到一完整指南
  • 门户网站建设公司网页设计风格分类
  • 综合整理:pdf预览显示:你尝试预览的文件可能对你的计算机有害。如果你信任此文件以及其来源,请打开此文件以看其内容,如何解决以正常预览文件
  • 微服务拆分之SpringCloud
  • Unity与iOS原生交互开发入门篇 - iOS原生弹窗与回调
  • 企业网站推广在哪里办成免费crm推广网站
  • 本地的赣州网站建设网站访问量asp
  • 总局核名的办理条件
  • 不只是计算:昇腾算子开发中的内存管理艺术
  • 深入解析 Spring Boot 自动配置:原理、实践与进阶​
  • 【Unity卷轴特效实现、原理、与深度解析】
  • STM32 串口中断接收原理与实战详解:从配置到中断服务函数全流程解析
  • 【Linux系统】C/C++的调试器gdb/cgdb,从入门到精通
  • 从被搜索到被推荐:GEO重塑可见性逻辑
  • 如何为 Oracle 数据库配置 TLS/TCPS
  • 阿里云网站备案注销吗大数据做网站
  • pc网站做app京东湖北网站推广服务
  • 测试环境与正式环境同样的机器显示不同的网络问题