前置知识: 软件测试

Selenium

00:00
3 min Intermediate 2026/6/14

Selenium Web自动化测试:WebDriver、定位策略、框架设计与最佳实践详解。

1. Selenium 概述

1.1 组件

组件描述
WebDriver浏览器自动化 API
IDE录制回放插件
Grid分布式测试

1.2 WebDriver 架构

测试代码 → WebDriver API → Browser Driver → 浏览器

2. 环境搭建

2.1 Python + Selenium

pip install selenium
pip install pytest

2.2 基础示例

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://example.com")

# 查找元素
element = driver.find_element(By.ID, "username")
element.send_keys("admin")

# 点击
driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click()

# 断言
assert "Dashboard" in driver.title

driver.quit()

3. 元素定位

3.1 定位策略

策略By 常量示例
IDBy.IDfind_element(By.ID, "login-btn")
NameBy.NAMEfind_element(By.NAME, "email")
ClassBy.CLASS_NAMEfind_element(By.CLASS_NAME, "btn-primary")
CSSBy.CSS_SELECTORfind_element(By.CSS_SELECTOR, "#login .btn")
XPathBy.XPATHfind_element(By.XPATH, "//button[@type='submit']")
TagBy.TAG_NAMEfind_element(By.TAG_NAME, "input")
LinkBy.LINK_TEXTfind_element(By.LINK_TEXT, "Login")
PartialBy.PARTIAL_LINK_TEXTfind_element(By.PARTIAL_LINK_TEXT, "Log")

3.2 推荐优先级

ID > CSS Selector > XPath > 其他

4. 等待机制

4.1 显式等待

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 等待元素可见
element = WebDriverWait(driver, 10).until(
    EC.visibility_of_element_located((By.ID, "result"))
)

# 等待元素可点击
element = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.CSS_SELECTOR, ".submit-btn"))
)

4.2 常用 Expected Conditions

条件描述
visibility_of_element_located元素可见
element_to_be_clickable元素
presence_of_element_located元素存在于 DOM
text_to_be_present_in_element文本出现
title_contains标题包含
url_containsURL

4.3 隐式等待

driver.implicitly_wait(10)  # 全局等待 10 秒

注意:不要混用显式和隐式等待。

5. Page Object 模式

5.1 页面对象

# pages/login_page.py
from selenium.webdriver.common.by import By

class LoginPage:
    def __init__(self, driver):
        self.driver = driver
        self.username_input = (By.ID, "username")
        self.password_input = (By.ID, "password")
        self.login_button = (By.CSS_SELECTOR, "button[type='submit']")

    def login(self, username, password):
        self.driver.find_element(*self.username_input).send_keys(username)
        self.driver.find_element(*self.password_input).send_keys(password)
        self.driver.find_element(*self.login_button).click()

5.2 测试用例

# tests/test_login.py
import pytest
from selenium import webdriver
from pages.login_page import LoginPage

class TestLogin:
    @pytest.fixture
    def driver(self):
        driver = webdriver.Chrome()
        driver.get("https://example.com/login")
        yield driver
        driver.quit()

    def test_successful_login(self, driver):
        login_page = LoginPage(driver)
        login_page.login("admin", "password123")
        assert "Dashboard" in driver.title

    def test_invalid_password(self, driver):
        login_page = LoginPage(driver)
        login_page.login("admin", "wrong")
        assert "Invalid credentials" in driver.page_source

6. 高级操作

6.1 多窗口

# 切换到新窗口
driver.switch_to.window(driver.window_handles[-1])

# 切换回主窗口
driver.switch_to.window(driver.window_handles[0])

6.2 iframe

driver.switch_to.frame("iframe-id")
# 操作 iframe 内元素
driver.switch_to.default_content()

6.3 下拉选择

from selenium.webdriver.support.select import Select

select = Select(driver.find_element(By.ID, "country"))
select.select_by_visible_text("China")
select.select_by_value("CN")
select.select_by_index(0)

6.4 截图

driver.save_screenshot("screenshot.png")
element.screenshot("element.png")

7. 最佳实践

实践描述
Page Object封装元素和操作
显式等待避免硬编码 sleep
数据驱动分离测试数据
失败失败时自动截
并行Grid/多线程
CI 集成Headless 模式
优先 CSSCSS 选择器优于 XPath

知识检测

学习进度

-- 已学文档
--% 知识覆盖率

学习推荐

专注模式