Selenium测试框架集成
Selenium 测试框架集成全攻略(2025 最新版)
Selenium + 框架 = 自动化测试工程化
掌握 unittest / pytest / TestNG + Page Object + 数据驱动 + 报告 + CI/CD,从脚本到生产级测试平台!
一、主流测试框架对比
| 框架 | 语言 | 优点 | 推荐场景 |
|---|---|---|---|
| unittest | Python | 内置、简单、类 JUnit | 入门、小项目 |
| pytest | Python | 强大、灵活、插件丰富 | 强烈推荐 |
| TestNG | Java | 注解强大、并行、数据驱动 | Java 项目 |
| JUnit 5 | Java | 现代、扩展性强 | Java 企业级 |
Python 推荐:
pytest
Java 推荐:TestNG
二、Python 集成:pytest + Selenium(王道组合)
1. 安装依赖
pip install selenium pytest pytest-html pytest-xdist webdriver-manager
2. 项目结构(推荐)
tests/
├── conftest.py # 全局 fixture
├── pages/ # Page Object
│ ├── base_page.py
│ ├── login_page.py
│ └── home_page.py
├── data/ # 测试数据
│ └── users.csv
├── utils/ # 工具函数
│ └── logger.py
├── reports/ # 自动生成
└── test_login.py
3. conftest.py —— 全局配置
# conftest.py
import pytest
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
@pytest.fixture(scope="session")
def driver():
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.maximize_window()
yield driver
driver.quit()
@pytest.fixture(autouse=True)
def screenshot_on_failure(request, driver):
yield
if request.node.rep_call.failed:
driver.save_screenshot(f"reports/{request.node.name}.png")
4. Page Object 模式(核心!)
# pages/base_page.py
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class BasePage:
def __init__(self, driver):
self.driver = driver
self.wait = WebDriverWait(driver, 10)
def click(self, locator):
self.wait.until(EC.element_to_be_clickable(locator)).click()
def send_keys(self, locator, text):
elem = self.wait.until(EC.presence_of_element_located(locator))
elem.clear()
elem.send_keys(text)
# pages/login_page.py
from selenium.webdriver.common.by import By
from .base_page import BasePage
class LoginPage(BasePage):
USERNAME = (By.ID, "username")
PASSWORD = (By.ID, "password")
LOGIN_BTN = (By.ID, "login")
ERROR_MSG = (By.CSS_SELECTOR, ".error")
def login(self, username, password):
self.send_keys(self.USERNAME, username)
self.send_keys(self.PASSWORD, password)
self.click(self.LOGIN_BTN)
def get_error(self):
return self.wait.until(EC.visibility_of_element_located(self.ERROR_MSG)).text
5. 数据驱动测试(CSV + @pytest.mark.parametrize)
# data/users.csv
username,password,expected
admin,123456,欢迎
wrong,123,用户名或密码错误
,123,请输入用户名
admin,,请输入密码
# test_login.py
import pytest
import csv
from pages.login_page import LoginPage
def get_test_data():
with open("data/users.csv") as f:
return list(csv.DictReader(f))
@pytest.mark.parametrize("data", get_test_data())
def test_login(driver, data):
login_page = LoginPage(driver)
driver.get("http://example.com/login")
login_page.login(data["username"], data["password"])
if "欢迎" in data["expected"]:
assert "首页" in driver.title
else:
assert data["expected"] in login_page.get_error()
6. 生成 HTML 报告
pytest --html=reports/report.html --self-contained-html
7. 并行执行(Grid 集成)
pytest -n 4 # 4 个并行
# conftest.py 改为 Remote
@pytest.fixture(scope="session")
def driver():
from selenium.webdriver import Remote
caps = {"browserName": "chrome", "platform": "ANY"}
driver = Remote(
command_executor="http://localhost:4444/wd/hub",
desired_capabilities=caps
)
yield driver
driver.quit()
三、Java 集成:TestNG + Selenium
1. pom.xml
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.25.0</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.8.0</version>
</dependency>
</dependencies>
2. testng.xml
<suite name="Login Suite" parallel="tests" thread-count="3">
<test name="Chrome Test">
<parameter name="browser" value="chrome"/>
<classes>
<class name="tests.LoginTest"/>
</classes>
</test>
</suite>
3. 测试类
// tests/LoginTest.java
@Test(dataProvider = "loginData")
public void testLogin(String username, String password, String expected) {
WebDriver driver = getDriver(browser);
LoginPage loginPage = new LoginPage(driver);
loginPage.login(username, password);
Assert.assertTrue(driver.getPageSource().contains(expected));
}
@DataProvider(name = "loginData")
public Object[][] loginData() {
return new Object[][] {
{"admin", "123456", "欢迎"},
{"wrong", "123", "错误"}
};
}
四、报告与日志
| 工具 | 语言 | 安装 |
|---|---|---|
| Allure | Python/Java | pip install allure-pytest |
| ExtentReports | Java | Maven |
| pytest-html | Python | pip install pytest-html |
pytest --alluredir=reports/allure
allure serve reports/allure
五、CI/CD 集成(GitHub Actions)
# .github/workflows/selenium.yml
name: Selenium Tests
on: [push]
jobs:
test:
runs-on: ubuntu-latest
services:
selenium:
image: selenium/standalone-chrome:4.25.0
ports: [4444:4444]
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with: { python-version: '3.11' }
- run: pip install -r requirements.txt
- run: pytest -n 2 --html=report.html
- uses: actions/upload-artifact@v3
with:
name: report
path: report.html
六、最佳实践总结(金字塔)
CI/CD
↑
报告 + 并行
↑
数据驱动 + Grid
↑
Page Object + 等待
↑
pytest / TestNG
↑
Selenium
七、一句话总结
Selenium + pytest + Page Object + Grid + Allure + GitHub Actions = 企业级自动化测试平台
八、完整项目模板(一键启动)
# 创建项目
mkdir selenium-framework && cd selenium-framework
pip install selenium pytest pytest-html webdriver-manager
# 生成结构
mkdir tests pages data reports utils
touch tests/conftest.py tests/test_login.py pages/{__init__,base_page,login_page}.py
# requirements.txt
selenium==4.25.0
pytest==8.0.0
pytest-html==4.1.1
webdriver-manager==4.0.2
allure-pytest==2.13.2
# 运行
pytest --html=reports/report.html --self-contained-html
下一步:
想获取 完整企业级测试框架模板(含登录、订单、报表、邮件通知、数据库验证)?
回复 framework_pro 我立刻发你一个 可直接部署的生产级项目!
当前最强组合:
pytest + Page Object + Selenium Grid + Allure + GitHub Actions
现在,你已拥有一个可扩展、可维护、可并行的自动化测试体系!