Selenium 简介 #
什么是 Selenium? #
Selenium 是一个强大的开源 Web 自动化测试框架,支持多种编程语言(Python、Java、JavaScript、C#、Ruby 等)和多种浏览器(Chrome、Firefox、Safari、Edge 等)。它允许开发者编写自动化脚本,模拟用户在浏览器中的操作行为,实现 Web 应用的功能测试、回归测试和端到端测试。
核心定位 #
text
┌─────────────────────────────────────────────────────────────┐
│ Selenium │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ WebDriver │ │ IDE │ │ Grid │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 多语言支持 │ │ 多浏览器 │ │ 分布式执行 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
Selenium 的历史 #
发展历程 #
text
2004年 ─── Selenium 项目启动
│
│ Jason Huggins 在 ThoughtWorks 创建
│ 最初用于内部 Web 应用测试
│
2006年 ─── Selenium RC 发布
│
│ 支持多种编程语言
│ 突破同源策略限制
│
2008年 ─── Selenium 2.0
│
│ 整合 WebDriver 项目
│ 全新的浏览器控制方式
│
2013年 ─── Selenium 3.0
│
│ 移除 Selenium RC
│ 全面拥抱 WebDriver
│
2018年 ─── Selenium 4.0 Alpha
│
│ W3C WebDriver 标准
│ 全新架构设计
│
2021年 ─── Selenium 4.0 正式版
│
│ 相对定位器
│ 增强的调试功能
│
至今 ─── 行业标准
│
│ 最流行的 Web 自动化框架
│ 超过 70% 的自动化项目使用
里程碑版本 #
| 版本 | 时间 | 重要特性 |
|---|---|---|
| 1.0 | 2006 | Selenium IDE、Selenium RC |
| 2.0 | 2011 | 整合 WebDriver、原生浏览器控制 |
| 3.0 | 2016 | 移除 RC、 Marionette 支持 |
| 4.0 | 2021 | W3C 标准、相对定位器、新 Grid |
Selenium 的三大组件 #
1. Selenium WebDriver #
WebDriver 是 Selenium 的核心组件,提供原生浏览器自动化能力:
text
┌─────────────────────────────────────────────────────────────┐
│ WebDriver 架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 测试代码 ──> WebDriver API ──> Browser Driver ──> 浏览器 │
│ │ │ │ │ │
│ Python/Java 统一接口 ChromeDriver Chrome │
│ JavaScript 跨语言 GeckoDriver Firefox │
│ C#/Ruby 跨浏览器 EdgeDriver Edge │
│ SafariDriver Safari │
│ │
└─────────────────────────────────────────────────────────────┘
2. Selenium IDE #
浏览器扩展工具,用于录制和回放测试:
text
┌─────────────────────────────────────────────────────────────┐
│ Selenium IDE │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 录制操作 │ │ 回放测试 │ │ 导出脚本 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ 适用场景: │
│ • 快速原型验证 │
│ • 简单测试用例录制 │
│ • 学习 Selenium 语法 │
│ • Bug 复现 │
│ │
└─────────────────────────────────────────────────────────────┘
3. Selenium Grid #
分布式测试执行平台:
text
┌─────────────────────────────────────────────────────────────┐
│ Selenium Grid │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ │
│ │ Hub │ │
│ │ (调度中心) │ │
│ └──────┬──────┘ │
│ │ │
│ ┌──────────────────┼──────────────────┐ │
│ │ │ │ │
│ ┌────▼────┐ ┌────▼────┐ ┌────▼────┐ │
│ │ Node1 │ │ Node2 │ │ Node3 │ │
│ │ Chrome │ │ Firefox │ │ Safari │ │
│ │ Windows │ │ Linux │ │ macOS │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
为什么选择 Selenium? #
传统手工测试的痛点 #
在没有自动化测试之前,Web 测试面临以下问题:
text
┌─────────────────────────────────────────────────────────────┐
│ 手工测试的问题 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ❌ 重复劳动:每次发版都要重复执行相同的测试用例 │
│ │
│ ❌ 效率低下:人工操作速度有限,无法快速完成大量测试 │
│ │
│ ❌ 容易出错:长时间重复操作容易疲劳和遗漏 │
│ │
│ ❌ 回归困难:功能增多后,回归测试工作量指数增长 │
│ │
│ ❌ 跨浏览器:需要在不同浏览器上重复测试 │
│ │
│ ❌ 持续集成:无法与 CI/CD 流程集成 │
│ │
└─────────────────────────────────────────────────────────────┘
Selenium 的解决方案 #
python
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://example.com/login")
driver.find_element(By.ID, "username").send_keys("user")
driver.find_element(By.ID, "password").send_keys("pass")
driver.find_element(By.ID, "submit").click()
assert "Welcome" in driver.title
driver.quit()
Selenium 的核心特点 #
1. 多语言支持 #
支持主流编程语言:
python
# Python
from selenium import webdriver
driver = webdriver.Chrome()
java
// Java
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
WebDriver driver = new ChromeDriver();
javascript
// JavaScript
const { Builder } = require('selenium-webdriver');
const driver = await new Builder().forBrowser('chrome').build();
csharp
// C#
using OpenQA.Selenium.Chrome;
var driver = new ChromeDriver();
2. 多浏览器支持 #
支持所有主流浏览器:
| 浏览器 | Driver | 支持程度 |
|---|---|---|
| Chrome | ChromeDriver | ✅ 完全支持 |
| Firefox | GeckoDriver | ✅ 完全支持 |
| Safari | SafariDriver | ✅ 完全支持 |
| Edge | EdgeDriver | ✅ 完全支持 |
| IE | IEDriver | ⚠️ 维护模式 |
3. 强大的定位能力 #
多种元素定位方式:
python
from selenium.webdriver.common.by import By
# ID 定位
driver.find_element(By.ID, "username")
# CSS 选择器
driver.find_element(By.CSS_SELECTOR, ".btn-primary")
# XPath
driver.find_element(By.XPATH, "//button[@type='submit']")
# 名称定位
driver.find_element(By.NAME, "email")
# 链接文本
driver.find_element(By.LINK_TEXT, "登录")
# 标签名
driver.find_element(By.TAG_NAME, "input")
4. 丰富的交互操作 #
模拟真实用户行为:
python
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
# 键盘操作
element.send_keys("Hello")
element.send_keys(Keys.ENTER)
# 鼠标操作
actions = ActionChains(driver)
actions.move_to_element(element).click().perform()
actions.double_click(element).perform()
actions.context_click(element).perform()
actions.drag_and_drop(source, target).perform()
5. 灵活的等待机制 #
智能等待元素:
python
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 显式等待
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "result"))
)
# 隐式等待
driver.implicitly_wait(10)
Selenium 与其他工具对比 #
Selenium vs Cypress #
| 特性 | Selenium | Cypress |
|---|---|---|
| 架构 | 浏览器外部 | 浏览器内部 |
| 语言支持 | ✅ 多语言 | ❌ 仅 JavaScript |
| 跨浏览器 | ✅ 全面 | ⚠️ 有限 |
| 执行速度 | ⚠️ 较慢 | ✅ 快 |
| 学习曲线 | ⚠️ 中等 | ✅ 低 |
| 生态系统 | ✅ 成熟 | 🔄 发展中 |
Selenium vs Playwright #
| 特性 | Selenium | Playwright |
|---|---|---|
| 语言支持 | ✅ 多语言 | ✅ 多语言 |
| 自动等待 | ⚠️ 需手动 | ✅ 内置 |
| 跨浏览器 | ✅ 全面 | ✅ 全面 |
| API 测试 | ❌ 不支持 | ✅ 支持 |
| 学习曲线 | ⚠️ 中等 | ⚠️ 中等 |
| 社区生态 | ✅ 成熟 | 🔄 快速发展 |
Selenium vs Puppeteer #
| 特性 | Selenium | Puppeteer |
|---|---|---|
| 语言支持 | ✅ 多语言 | ❌ 仅 JavaScript |
| 浏览器 | ✅ 多浏览器 | ❌ 仅 Chrome |
| 定位 | 测试框架 | 自动化工具 |
| 学习曲线 | ⚠️ 中等 | ⚠️ 中等 |
| 社区生态 | ✅ 成熟 | ✅ 成熟 |
Selenium 的应用场景 #
1. 功能测试 #
验证 Web 应用功能:
python
def test_login():
driver = webdriver.Chrome()
driver.get("https://example.com/login")
driver.find_element(By.ID, "username").send_keys("user")
driver.find_element(By.ID, "password").send_keys("pass")
driver.find_element(By.ID, "submit").click()
assert "Dashboard" in driver.title
driver.quit()
2. 回归测试 #
确保新代码不破坏现有功能:
python
import pytest
class TestRegression:
@pytest.fixture(autouse=True)
def setup(self):
self.driver = webdriver.Chrome()
yield
self.driver.quit()
def test_homepage(self):
self.driver.get("https://example.com")
assert self.driver.title == "Home"
def test_search(self):
self.driver.get("https://example.com/search")
self.driver.find_element(By.NAME, "q").send_keys("test")
assert len(self.driver.find_elements(By.CLASS_NAME, "result")) > 0
3. 跨浏览器测试 #
验证不同浏览器兼容性:
python
import pytest
@pytest.fixture(params=["chrome", "firefox", "edge"])
def driver(request):
if request.param == "chrome":
driver = webdriver.Chrome()
elif request.param == "firefox":
driver = webdriver.Firefox()
else:
driver = webdriver.Edge()
yield driver
driver.quit()
def test_cross_browser(driver):
driver.get("https://example.com")
assert driver.title
4. 数据驱动测试 #
使用多组数据测试:
python
import pytest
@pytest.mark.parametrize("username,password,expected", [
("user1", "pass1", "success"),
("user2", "pass2", "success"),
("invalid", "invalid", "error"),
])
def test_login_data_driven(username, password, expected):
driver = webdriver.Chrome()
driver.get("https://example.com/login")
driver.find_element(By.ID, "username").send_keys(username)
driver.find_element(By.ID, "password").send_keys(password)
driver.find_element(By.ID, "submit").click()
if expected == "success":
assert "Dashboard" in driver.title
else:
assert "Error" in driver.page_source
driver.quit()
5. 性能测试 #
测量页面加载时间:
python
from time import time
def test_page_performance():
driver = webdriver.Chrome()
start = time()
driver.get("https://example.com")
load_time = time() - start
print(f"Page load time: {load_time:.2f}s")
assert load_time < 3.0 # 页面应在 3 秒内加载完成
driver.quit()
Selenium 的核心概念 #
WebDriver 接口 #
python
# WebDriver 是核心接口
driver = webdriver.Chrome()
# 导航操作
driver.get("https://example.com")
driver.back()
driver.forward()
driver.refresh()
# 获取信息
current_url = driver.current_url
title = driver.title
page_source = driver.page_source
# 窗口管理
driver.maximize_window()
driver.set_window_size(1024, 768)
WebElement 接口 #
python
# WebElement 表示页面元素
element = driver.find_element(By.ID, "username")
# 获取元素信息
text = element.text
attribute = element.get_attribute("value")
is_displayed = element.is_displayed()
is_enabled = element.is_enabled()
is_selected = element.is_selected()
# 执行操作
element.click()
element.send_keys("Hello")
element.clear()
定位器策略 #
python
from selenium.webdriver.common.by import By
# 八种定位策略
By.ID # 通过 ID 属性
By.NAME # 通过 name 属性
By.CLASS_NAME # 通过 class 属性
By.TAG_NAME # 通过标签名
By.LINK_TEXT # 通过链接完整文本
By.PARTIAL_LINK_TEXT # 通过链接部分文本
By.CSS_SELECTOR # 通过 CSS 选择器
By.XPATH # 通过 XPath 表达式
Selenium 的设计哲学 #
1. 语言无关性 #
text
┌─────────────────────────────────────────────────────────────┐
│ 语言无关性设计 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Python ──┐ │
│ │ │
│ Java ────┼──> WebDriver API ──> JSON Wire Protocol │
│ │ │
│ JavaScript──┤ │ │
│ │ │ │
│ C# ──────┘ ▼ │
│ Browser Driver │
│ │ │
│ ▼ │
│ 浏览器 │
│ │
└─────────────────────────────────────────────────────────────┘
2. 浏览器无关性 #
统一的 API,不同的实现:
python
# 相同的代码,不同的浏览器
chrome_driver = webdriver.Chrome()
firefox_driver = webdriver.Firefox()
edge_driver = webdriver.Edge()
# 所有浏览器使用相同的 API
for driver in [chrome_driver, firefox_driver, edge_driver]:
driver.get("https://example.com")
driver.find_element(By.ID, "test").click()
driver.quit()
3. 可扩展性 #
支持自定义扩展:
python
# 自定义 WebElement 扩展
class CustomElement:
def __init__(self, element):
self.element = element
def highlight(self):
driver = self.element._parent
driver.execute_script(
"arguments[0].style.border='3px solid red'",
self.element
)
return self.element
Selenium 的局限性 #
已知限制 #
- 速度较慢:相比浏览器内部框架,执行速度较慢
- 无内置等待:需要手动处理等待逻辑
- 无 API 测试:不支持 API 层面的测试
- 维护成本:元素定位器容易因 UI 变化而失效
解决方案 #
python
# 使用显式等待提高稳定性
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "button"))
)
# 使用 Page Object 模式降低维护成本
class LoginPage:
def __init__(self, driver):
self.driver = driver
self.username = (By.ID, "username")
self.password = (By.ID, "password")
self.submit = (By.ID, "submit")
def login(self, user, passw):
self.driver.find_element(*self.username).send_keys(user)
self.driver.find_element(*self.password).send_keys(passw)
self.driver.find_element(*self.submit).click()
学习路径 #
text
入门阶段
├── 安装与配置
├── 编写第一个脚本
├── 元素定位基础
└── 基本交互操作
进阶阶段
├── 高级定位策略
├── 等待机制
├── 用户交互模拟
└── 多窗口/框架处理
高级阶段
├── Actions 链操作
├── Page Object 模式
├── Pytest 集成
└── 测试框架设计
扩展阶段
├── Selenium Grid
├── CI/CD 集成
├── 性能监控
└── 最佳实践
下一步 #
现在你已经了解了 Selenium 的基本概念,接下来学习 安装与配置 开始实际使用 Selenium!
最后更新:2026-03-28