Python自动化测试Selenium教程


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("请在页面输入验证码后按回车继续...")

九、最佳实践建议

  1. 使用明确的等待:避免使用time.sleep(),优先使用WebDriverWait
  2. 保持代码整洁:遵循Page Object模式,分离测试逻辑和页面操作
  3. 合理使用定位器:优先使用ID、name等稳定属性,谨慎使用XPath
  4. 添加测试断言:每个测试用例应有明确的验证点
  5. 处理测试数据:使用独立的数据文件或生成测试数据
  6. 添加日志记录:记录测试执行过程便于排查问题
  7. 异常处理:合理处理可能出现的异常情况
  8. 跨浏览器测试:考虑在不同浏览器上运行测试

十、总结

本教程全面介绍了Python+Selenium自动化测试的核心技术,包括:

  • 环境搭建与基础使用
  • 元素定位与操作技巧
  • 三种等待机制的应用场景
  • 高级操作如iframe处理、文件上传等
  • 与unittest/pytest测试框架集成
  • Page Object设计模式
  • 常见问题解决方案

Selenium是一个功能强大的自动化测试工具,结合Python可以构建灵活、高效的测试解决方案。希望本教程能帮助您快速掌握Web自动化测试技能,在实际项目中发挥作用。

,

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注