1. Selenium自动化测试入门指南
刚接触Web自动化测试时,我踩过不少坑。记得第一次用Selenium时,光是环境配置就折腾了大半天。现在回想起来,如果当时有人能系统地告诉我这些经验,至少能节省两周的摸索时间。这篇文章就是我想写给当初那个自己的实战手册。
Selenium是目前最主流的Web自动化测试框架之一,配合Python使用可以快速构建稳定可靠的测试脚本。不同于简单的单元测试,它能真实模拟用户操作浏览器,从点击按钮到填写表单,甚至处理弹窗和iframe都不在话下。我经手过的电商平台、ERP系统和移动端H5页面,90%的UI测试场景都能用它搞定。
2. 环境搭建与基础配置
2.1 安装必备组件
首先需要安装Python环境(推荐3.7+版本),然后通过pip安装selenium包:
bash复制pip install selenium
浏览器驱动是很多人容易忽略的关键组件。以Chrome为例,需要下载与本地浏览器版本匹配的chromedriver。我习惯把驱动放在项目根目录下的drivers文件夹,方便版本管理:
python复制from selenium import webdriver
driver = webdriver.Chrome(executable_path='./drivers/chromedriver')
注意:浏览器和驱动版本必须严格匹配,否则会出现各种诡异问题。我维护了一个版本对照表,每次升级前都会先核对。
2.2 基础配置参数
启动浏览器时建议添加这些实用参数:
python复制options = webdriver.ChromeOptions()
options.add_argument('--headless') # 无头模式
options.add_argument('--disable-gpu') # 禁用GPU加速
options.add_argument('--window-size=1920x1080') # 设置窗口尺寸
driver = webdriver.Chrome(options=options)
无头模式特别适合在CI/CD流水线中运行测试,能节省大量资源。不过调试阶段建议保持可视化,方便定位问题。
3. 核心元素定位策略
3.1 八大定位方式实战
Selenium提供了多种元素定位方法,根据我的经验这样选择最靠谱:
- ID定位 - 最可靠的首选方案
python复制search_box = driver.find_element_by_id("kw")
- CSS选择器 - 灵活性强,适合复杂结构
python复制submit_btn = driver.find_element_by_css_selector("#form > button.primary")
- XPath - 终极武器,但维护成本高
python复制menu_item = driver.find_element_by_xpath("//ul[@class='nav']/li[3]")
其他如name、class_name、link_text等也有特定使用场景。我整理过定位策略优先级:ID > CSS > XPath > 其他。
3.2 智能等待机制
元素加载时机是自动化测试中最常见的痛点。硬性等待(time.sleep)是下下策,应该使用显式等待:
python复制from selenium.webdriver.common.by import By
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, "dynamicElement"))
)
这套组合拳能智能等待元素出现,最多等待10秒。我常用的条件还有:
- element_to_be_clickable
- visibility_of_element_located
- text_to_be_present_in_element
4. 高级交互技巧
4.1 复杂动作链
有些交互需要组合多个动作,比如拖放、长按等。ActionChains可以完美处理:
python复制from selenium.webdriver.common.action_chains import ActionChains
source = driver.find_element_by_id("draggable")
target = driver.find_element_by_id("droppable")
ActionChains(driver).drag_and_drop(source, target).perform()
我常用它来处理:
- 悬浮菜单触发
- 画板涂鸦操作
- 滑动验证码破解(合法测试用途)
4.2 文件上传处理
文件上传是另一个常见难点。不要尝试模拟点击上传按钮,直接send_keys最可靠:
python复制upload = driver.find_element_by_id("fileInput")
upload.send_keys("/path/to/testfile.jpg")
如果遇到隐藏的input元素,需要用JS先使其可见:
python复制driver.execute_script("arguments[0].style.display='block';", upload)
upload.send_keys("/path/to/file")
5. 测试框架集成
5.1 unittest整合方案
Python自带的unittest框架能与Selenium完美配合:
python复制import unittest
class TestLogin(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.driver = webdriver.Chrome()
def test_valid_login(self):
self.driver.get("https://example.com/login")
# 测试步骤...
self.assertIn("Dashboard", self.driver.title)
@classmethod
def tearDownClass(cls):
cls.driver.quit()
我习惯在每个测试用例中加截图功能,失败时自动保存现场:
python复制def tearDown(self):
if sys.exc_info()[0]:
self.driver.save_screenshot(f"error_{self._testMethodName}.png")
5.2 pytest进阶用法
pytest框架更灵活,配合插件威力更大:
python复制# conftest.py
@pytest.fixture(scope="module")
def browser():
driver = webdriver.Chrome()
yield driver
driver.quit()
# test_search.py
def test_search(browser):
browser.get("https://example.com")
# 测试代码...
推荐安装这些插件:
- pytest-html:生成精美报告
- pytest-xdist:并行执行测试
- pytest-rerunfailures:失败重试
6. 企业级实战经验
6.1 Page Object模式
大型项目必须采用Page Object设计模式:
python复制class LoginPage:
def __init__(self, driver):
self.driver = driver
self.username = (By.ID, "username")
self.password = (By.ID, "password")
def enter_credentials(self, user, pwd):
self.driver.find_element(*self.username).send_keys(user)
self.driver.find_element(*self.password).send_keys(pwd)
def submit(self):
self.driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click()
这种模式的优势:
- 元素定位与业务逻辑分离
- 复用性强
- 维护成本低
6.2 自动化测试平台集成
在企业级CI/CD流程中,我通常这样集成:
- Jenkins创建自动化测试任务
- 使用Docker容器运行测试
dockerfile复制FROM python:3.8
RUN pip install selenium pytest
COPY . /app
WORKDIR /app
CMD ["pytest", "tests/", "--html=report.html"]
- 测试结果通过邮件/钉钉通知
- Allure生成可视化报告
7. 疑难问题解决方案
7.1 验证码处理策略
测试环境可以暂时禁用验证码,或者使用万能验证码。如果必须处理:
python复制# 简单数字验证码OCR识别(成功率约70%)
import pytesseract
from PIL import Image
captcha = driver.find_element_by_id("captcha")
captcha.screenshot("captcha.png")
text = pytesseract.image_to_string(Image.open("captcha.png"))
driver.find_element_by_id("captchaInput").send_keys(text)
更复杂的验证码建议联系开发提供测试专用接口。
7.2 浏览器弹窗处理
各种弹窗需要不同处理方式:
python复制# alert弹窗
alert = driver.switch_to.alert
alert.accept() # 确认
alert.dismiss() # 取消
# 新窗口切换
main_window = driver.current_window_handle
for handle in driver.window_handles:
if handle != main_window:
driver.switch_to.window(handle)
# iframe嵌套
driver.switch_to.frame("iframeName")
# 操作iframe内元素...
driver.switch_to.default_content()
8. 性能优化技巧
8.1 测试加速方案
- 并行测试:使用pytest-xdist同时运行多个用例
bash复制pytest -n 4 # 使用4个worker
- 浏览器复用:通过remote复用已有实例
python复制driver = webdriver.Remote(
command_executor='http://127.0.0.1:4444/wd/hub',
options=webdriver.ChromeOptions()
)
- 网络模拟:使用Chrome DevTools Protocol模拟弱网
python复制from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
caps = DesiredCapabilities.CHROME
caps['goog:loggingPrefs'] = {'performance': 'ALL'}
driver = webdriver.Chrome(desired_capabilities=caps)
8.2 智能等待优化
我封装了一个智能等待工具类:
python复制def smart_wait(driver, locator, timeout=10):
try:
return WebDriverWait(driver, timeout).until(
lambda d: d.find_element(*locator).is_displayed()
)
except:
driver.save_screenshot("timeout_error.png")
raise
这个方案会:
- 等待元素可见
- 超时自动截图
- 抛出详细异常
9. 移动端测试适配
9.1 移动端模拟配置
通过Chrome选项模拟移动设备:
python复制mobile_emulation = {
"deviceMetrics": {"width": 375, "height": 812, "pixelRatio": 3.0},
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X)..."
}
options.add_experimental_option("mobileEmulation", mobile_emulation)
9.2 真机测试方案
使用Appium+Selenium测试原生APP/H5:
python复制desired_caps = {
'platformName': 'Android',
'deviceName': 'Pixel_3a',
'browserName': 'Chrome'
}
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
10. 持续维护建议
- 元素定位器统一管理:
python复制# locators.py
class LoginPageLocators:
USERNAME = (By.ID, "username")
PASSWORD = (By.ID, "password")
- 定期更新浏览器驱动
- 添加测试数据清理逻辑
- 使用版本控制管理测试脚本
这套Selenium实战方案已经在我们团队稳定运行3年,每天执行2000+测试用例。核心经验是:保持脚本简洁、做好异常处理、重视可维护性。当你的测试代码比业务代码还复杂时,就该考虑重构了。