Selenium是当前最流行的Web自动化测试工具之一,结合Python可以构建强大的自动化测试解决方案。本教程将全面介绍如何使用Python和Selenium进行Web自动化测试,从环境搭建到高级应用技巧。
一、Selenium环境搭建
1. 安装必要组件
# 安装selenium库
pip install selenium
# 安装浏览器驱动(以Chrome为例)
# 需要下载与浏览器版本匹配的chromedriver
# 下载地址:https://chromedriver.chromium.org/downloads
2. 配置浏览器驱动
将下载的chromedriver.exe放在以下位置之一:
- Python安装目录下的Scripts文件夹
- 系统PATH环境变量包含的目录
- 项目中指定路径(需要在代码中指定路径)
二、Selenium基础使用
1. 启动浏览器
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
# 方式1:自动查找PATH中的驱动
driver = webdriver.Chrome()
# 方式2:指定驱动路径
service = Service(executable_path='path/to/chromedriver')
driver = webdriver.Chrome(service=service)
# 访问网页
driver.get("https://www.baidu.com")
# 关闭浏览器
driver.quit()
2. 常用浏览器操作
# 浏览器窗口操作
driver.maximize_window() # 最大化窗口
driver.minimize_window() # 最小化窗口
driver.set_window_size(1200, 800) # 设置窗口大小
# 页面导航
driver.back() # 后退
driver.forward() # 前进
driver.refresh() # 刷新
# 获取页面信息
print(driver.title) # 页面标题
print(driver.current_url) # 当前URL
print(driver.page_source) # 页面源码
三、元素定位与操作
Selenium提供了8种元素定位方式:
1. 元素定位方法
from selenium.webdriver.common.by import By
# 通过ID定位
element = driver.find_element(By.ID, "kw")
# 通过name定位
element = driver.find_element(By.NAME, "wd")
# 通过class name定位
element = driver.find_element(By.CLASS_NAME, "s_ipt")
# 通过tag name定位
element = driver.find_element(By.TAG_NAME, "input")
# 通过link text定位(精确匹配)
element = driver.find_element(By.LINK_TEXT, "新闻")
# 通过partial link text定位(部分匹配)
element = driver.find_element(By.PARTIAL_LINK_TEXT, "闻")
# 通过CSS选择器定位
element = driver.find_element(By.CSS_SELECTOR, "#kw")
# 通过XPath定位
element = driver.find_element(By.XPATH, "//input[@id='kw']")
2. 元素常用操作
# 输入文本
element.send_keys("Python自动化测试")
# 清除内容
element.clear()
# 点击元素
element.click()
# 获取元素属性
print(element.get_attribute("value"))
# 获取元素文本
print(element.text)
# 判断元素是否可见/可用/被选中
print(element.is_displayed())
print(element.is_enabled())
print(element.is_selected())
四、等待机制
1. 强制等待(不推荐)
import time
time.sleep(3) # 强制等待3秒
2. 隐式等待
# 设置全局等待时间(作用于所有find_element操作)
driver.implicitly_wait(10) # 最多等待10秒
3. 显式等待(推荐)
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 等待元素出现(最多10秒,每0.5秒检查一次)
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "kw"))
)
# 其他常用条件
EC.title_is("百度一下") # 标题等于
EC.title_contains("百度") # 标题包含
EC.visibility_of_element_located((By.ID, "kw")) # 元素可见
EC.element_to_be_clickable((By.ID, "su")) # 元素可点击
五、高级操作
1. 处理iframe
# 切换到iframe
driver.switch_to.frame("iframe_id") # 通过id/name
driver.switch_to.frame(driver.find_element(By.TAG_NAME, "iframe")) # 通过元素
# 切回主文档
driver.switch_to.default_content()
# 切回父iframe
driver.switch_to.parent_frame()
2. 处理JavaScript弹窗
# 获取alert对象
alert = driver.switch_to.alert
# 操作alert
print(alert.text) # 获取文本
alert.accept() # 确认
alert.dismiss() # 取消
alert.send_keys("输入内容") # 输入内容
3. 执行JavaScript代码
# 执行JS脚本
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# 通过JS操作元素
element = driver.find_element(By.ID, "kw")
driver.execute_script("arguments[0].click();", element)
4. 文件上传
# 定位文件上传input元素
upload = driver.find_element(By.ID, "file-upload")
# 发送文件路径(不要使用click())
upload.send_keys("/path/to/file.txt")
5. 浏览器多窗口/标签页处理
# 获取当前窗口句柄
main_window = driver.current_window_handle
# 获取所有窗口句柄
all_windows = driver.window_handles
# 切换到新窗口
for window in all_windows:
if window != main_window:
driver.switch_to.window(window)
# 关闭当前窗口并切换回主窗口
driver.close()
driver.switch_to.window(main_window)
六、测试框架集成
1. 结合unittest框架
import unittest
from selenium import webdriver
class TestBaiduSearch(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.driver = webdriver.Chrome()
cls.driver.implicitly_wait(10)
def test_search(self):
self.driver.get("https://www.baidu.com")
self.driver.find_element(By.ID, "kw").send_keys("Python")
self.driver.find_element(By.ID, "su").click()
self.assertIn("Python", self.driver.title)
@classmethod
def tearDownClass(cls):
cls.driver.quit()
if __name__ == "__main__":
unittest.main()
2. 结合pytest框架
import pytest
from selenium import webdriver
@pytest.fixture(scope="module")
def driver():
d = webdriver.Chrome()
yield d
d.quit()
def test_baidu_search(driver):
driver.get("https://www.baidu.com")
driver.find_element(By.ID, "kw").send_keys("pytest")
driver.find_element(By.ID, "su").click()
assert "pytest" in driver.title
七、Page Object模式(推荐)
Page Object模式将页面封装为类,提高代码复用性和可维护性。
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class LoginPage:
def __init__(self, driver):
self.driver = driver
self.username_locator = (By.ID, "username")
self.password_locator = (By.ID, "password")
self.submit_locator = (By.ID, "submit")
def enter_username(self, username):
WebDriverWait(self.driver, 10).until(
EC.visibility_of_element_located(self.username_locator)
).send_keys(username)
def enter_password(self, password):
self.driver.find_element(*self.password_locator).send_keys(password)
def click_submit(self):
self.driver.find_element(*self.submit_locator).click()
# 使用示例
driver = webdriver.Chrome()
login_page = LoginPage(driver)
login_page.enter_username("testuser")
login_page.enter_password("password")
login_page.click_submit()
八、常见问题解决方案
1. 处理元素不可点击异常
from selenium.webdriver.common.action_chains import ActionChains
element = driver.find_element(By.ID, "menu")
ActionChains(driver).move_to_element(element).click().perform()
2. 处理StaleElementReferenceException
def safe_click(element_locator, timeout=10):
def _wrap(driver):
try:
element = WebDriverWait(driver, timeout).until(
EC.presence_of_element_located(element_locator)
)
element.click()
return True
except StaleElementReferenceException:
return False
return _wrap
WebDriverWait(driver, 30).until(
safe_click((By.ID, "dynamic-element"))
)
3. 处理验证码问题
# 方案1:测试环境禁用验证码
# 方案2:设置万能验证码
# 方案3:人工干预(不推荐)
input("请在页面输入验证码后按回车继续...")
九、最佳实践建议
- 使用明确的等待:避免使用time.sleep(),优先使用WebDriverWait
- 保持代码整洁:遵循Page Object模式,分离测试逻辑和页面操作
- 合理使用定位器:优先使用ID、name等稳定属性,谨慎使用XPath
- 添加测试断言:每个测试用例应有明确的验证点
- 处理测试数据:使用独立的数据文件或生成测试数据
- 添加日志记录:记录测试执行过程便于排查问题
- 异常处理:合理处理可能出现的异常情况
- 跨浏览器测试:考虑在不同浏览器上运行测试
十、总结
本教程全面介绍了Python+Selenium自动化测试的核心技术,包括:
- 环境搭建与基础使用
- 元素定位与操作技巧
- 三种等待机制的应用场景
- 高级操作如iframe处理、文件上传等
- 与unittest/pytest测试框架集成
- Page Object设计模式
- 常见问题解决方案
Selenium是一个功能强大的自动化测试工具,结合Python可以构建灵活、高效的测试解决方案。希望本教程能帮助您快速掌握Web自动化测试技能,在实际项目中发挥作用。