Selenium - WebDriver
Selenium - WebDriver
Section titled “Selenium - WebDriver”Selenium WebDriver 是现代 Selenium 套件的核心组件。它提供了一个编程接口(API),通过直接控制 Web 浏览器来创建和运行自动化测试。与它的前身 Selenium RC 不同,WebDriver 使用浏览器供应商的原生自动化支持与浏览器交互,从而实现更稳定和更快的测试。
WebDriver 的主要特点:
- 直接浏览器控制: 直接与浏览器驱动程序通信(例如,ChromeDriver、GeckoDriver)。
- 语言绑定: 为各种编程语言(Java、Python、C#、Ruby、JavaScript)提供 API。
- 跨浏览器支持: 支持在主要浏览器(Chrome、Firefox、Edge、Safari、IE)上进行自动化。
- 跨平台支持: 在 Windows、macOS 和 Linux 上运行。
- 面向对象 API: 与 Selenium RC 相比,提供了更清晰、更一致的 API。
- 处理现代 Web 技术: 更适合处理动态网页、AJAX、框架、窗口和弹窗(alerts)。
WebDriver 架构
Section titled “WebDriver 架构”WebDriver 架构比 Selenium RC 更简单:
- Selenium 客户端库(语言绑定): 你使用 Selenium API 编写的测试脚本,例如使用 Java、Python 等。
- JSON Wire Protocol / W3C WebDriver Protocol: 客户端库通过 HTTP 发送命令的标准化方式。
- 浏览器驱动程序: 由浏览器供应商提供的可执行文件(例如,
chromedriver.exe、geckodriver.exe)。它们充当服务器,监听命令。 - 浏览器: 实际的浏览器(Chrome、Firefox 等)从各自的驱动程序接收命令并执行它们。
你的脚本通过协议向浏览器驱动程序发送命令(如 ‘查找元素’、‘点击元素’)。然后驱动程序使用浏览器内置的自动化钩子执行命令,并将结果返回给你的脚本。
WebDriver 对比 Selenium RC(旧版)
Section titled “WebDriver 对比 Selenium RC(旧版)”| 特性 | Selenium WebDriver(现代) | Selenium RC(已弃用) |
|---|---|---|
| 架构 | 更简单:脚本 -> 驱动程序 -> 浏览器 | 复杂:脚本 -> RC 服务器 -> 浏览器(通过 JS 注入) |
| 通信 | 通过 WebDriver protocol 直接通信 (HTTP) | 通过 RC 服务器代理间接通信 |
| 速度 | 更快 | 由于额外跳跃和 JS 执行而较慢 |
| API | 面向对象,更清晰 | 不太面向对象,更偏向过程化 |
| 浏览器交互 | 使用原生浏览器自动化 | 依赖于 JavaScript (Selenium Core) 注入 |
| 无头模式执行 | 大多数现代浏览器/驱动程序支持 | 不直接支持 |
| 当前状态 | 积极开发中 & 推荐标准 | 已弃用,不再支持 |
基本的 WebDriver 脚本(Java 示例)
Section titled “基本的 WebDriver 脚本(Java 示例)”让我们使用 WebDriver、Java、TestNG 和 WebDriverManager(推荐用于驱动程序管理)编写一个简单的脚本。我们将自动化 Google 搜索。
先决条件:Java、Maven/Gradle、IDE(Eclipse/IntelliJ)。
- 项目设置: 创建一个 Maven 项目,并将 Selenium 和 TestNG 依赖项添加到你的
pom.xml中:
<dependencies> <!-- Selenium Java --> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>4.10.0</version> <!-- Use latest version --> </dependency>
<!-- TestNG --> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>7.7.1</version> <!-- Use latest version --> <scope>test</scope> </dependency>
<!-- WebDriverManager --> <dependency> <groupId>io.github.bonigarcia</groupId> <artifactId>webdrivermanager</artifactId> <version>5.3.3</version> <!-- Use latest version --> <scope>test</scope> </dependency></dependencies>- 创建测试类:
package com.example.tests;
import io.github.bonigarcia.wdm.WebDriverManager;import org.openqa.selenium.By;import org.openqa.selenium.Keys;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.chrome.ChromeDriver;import org.openqa.selenium.support.ui.ExpectedConditions;import org.openqa.selenium.support.ui.WebDriverWait;import org.testng.Assert;import org.testng.annotations.AfterMethod;import org.testng.annotations.BeforeMethod;import org.testng.annotations.Test;
import java.time.Duration;
public class GoogleSearchTest {
WebDriver driver; WebDriverWait wait;
@BeforeMethod public void setup() { // WebDriverManager 自动下载并设置 ChromeDriver WebDriverManager.chromedriver().setup(); driver = new ChromeDriver(); wait = new WebDriverWait(driver, Duration.ofSeconds(10)); // 显式等待(10 秒超时) driver.manage().window().maximize(); }
@Test public void testGoogleSearch() { // 导航到 Google driver.get("https://www.google.com");
// 查找搜索框(使用 name 定位器) // 等待元素出现后再交互 WebElement searchBox = wait.until(ExpectedConditions.presenceOfElementLocated(By.name("q")));
// 输入搜索词并按 Enter searchBox.sendKeys("Selenium WebDriver"); searchBox.sendKeys(Keys.ENTER);
// 等待结果页标题包含搜索词 wait.until(ExpectedConditions.titleContains("Selenium WebDriver"));
// 断言标题包含搜索词 Assert.assertTrue(driver.getTitle().contains("Selenium WebDriver"), "Page title does not contain search term.");
// 查找并断言搜索结果统计信息显示 WebElement resultStats = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("result-stats"))); Assert.assertTrue(resultStats.isDisplayed(), "Result stats not found.");
System.out.println("Google search test passed!"); }
@AfterMethod public void tearDown() { if (driver != null) { driver.quit(); // 关闭所有浏览器窗口并结束 WebDriver 会话 } }}- 运行测试: 从你的 IDE 中将此类作为 TestNG 测试运行。
常用的 WebDriver 命令
Section titled “常用的 WebDriver 命令”以下是常用 WebDriver 命令的摘要:
| 命令 | 描述 |
|---|---|
driver.get("URL") | 导航到指定的 URL。 |
driver.findElement(By locator) | 查找匹配定位器的第一个元素。 |
driver.findElements(By locator) | 查找匹配定位器的所有元素。 |
element.click() | 点击元素。 |
element.sendKeys("text") | 将文本输入到元素中。 |
element.clear() | 清除输入元素中的文本。 |
element.getText() | 获取元素的可见文本。 |
element.getAttribute("attr") | 获取元素的属性值。 |
element.isDisplayed(), isEnabled(), isSelected() | 检查元素的状态。 |
driver.getTitle() | 获取当前页面的标题。 |
driver.getCurrentUrl() | 获取当前页面的 URL。 |
driver.navigate().back(), forward(), refresh() | 执行浏览器导航操作。 |
driver.switchTo().frame(index/name/WebElement) | 切换焦点到 iframe。 |
driver.switchTo().defaultContent() | 将焦点从框架切换回主页面。 |
driver.switchTo().window(windowHandle) | 在浏览器窗口/标签页之间切换焦点。 |
driver.switchTo().alert().accept(), dismiss(), getText(), sendKeys() | 处理 JavaScript 弹窗(alert、confirm、prompt)。 |
driver.manage().window().maximize(), minimize(), setSize() | 控制浏览器窗口大小和状态。 |
driver.manage().timeouts().implicitlyWait(Duration) | 设置隐式等待时间(谨慎使用,优先使用显式等待)。 |
new WebDriverWait(driver, Duration).until(ExpectedCondition) | 设置显式等待直到满足特定条件。 |
driver.quit() | 关闭所有关联的浏览器窗口并结束会话。 |
driver.close() | 关闭当前焦点的浏览器窗口。 |