当前位置: 首页 > news >正文

Python 自动化测试开发教程:Selenium 从入门到实战(1)

Selenium 是目前最流行的 Web 自动化测试工具之一,它可以模拟用户在浏览器中的各种操作,实现 Web 应用的自动化测试。本教程将带你从零基础开始,逐步掌握 Selenium 的核心用法和实战技巧。

一、环境搭建

1. 安装 Selenium

首先需要安装 Selenium 库:

pip install selenium

2. 安装浏览器驱动

Selenium 需要浏览器驱动才能控制浏览器,不同浏览器需要对应版本的驱动:

  • Chrome: ChromeDriver
  • Firefox: GeckoDriver
  • Edge: EdgeDriver

安装步骤:

  1. 下载与你的浏览器版本匹配的驱动
  2. 将驱动文件所在目录添加到系统 PATH 环境变量
  3. 验证安装:在命令行输入驱动名称(如 chromedriver),能看到版本信息即安装成功

二、Selenium 基础用法

1. 第一个 Selenium 程序

下面是一个简单的示例,演示如何打开浏览器、访问网页并获取页面标题:

from selenium import webdriver
from selenium.webdriver.common.by import By# 初始化浏览器驱动(这里使用Chrome)
driver = webdriver.Chrome()# 打开网页
driver.get("https://www.baidu.com")# 打印页面标题
print("页面标题:", driver.title)# 查找搜索框并输入内容
search_box = driver.find_element(By.ID, "kw")
search_box.send_keys("Selenium 教程")# 查找搜索按钮并点击
search_button = driver.find_element(By.ID, "su")
search_button.click()# 等待3秒,让页面加载完成
import time
time.sleep(3)# 关闭浏览器
driver.quit()

2. 元素定位方法

Selenium 提供了多种元素定位方式,常用的有:

from selenium import webdriver
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
driver.get("https://example.com")# 1. 通过ID定位
element = driver.find_element(By.ID, "some-id")# 2. 通过Name定位
element = driver.find_element(By.NAME, "some-name")# 3. 通过Class Name定位
element = driver.find_element(By.CLASS_NAME, "some-class")# 4. 通过Tag Name定位
element = driver.find_element(By.TAG_NAME, "div")# 5. 通过Link Text定位(精确匹配)
element = driver.find_element(By.LINK_TEXT, "点击这里")# 6. 通过Partial Link Text定位(部分匹配)
element = driver.find_element(By.PARTIAL_LINK_TEXT, "点击")# 7. 通过CSS选择器定位
element = driver.find_element(By.CSS_SELECTOR, "div.some-class > p#some-id")# 8. 通过XPath定位
element = driver.find_element(By.XPATH, "//div[@class='some-class']/p")# 查找多个元素(返回列表)
elements = driver.find_elements(By.TAG_NAME, "a")
print(f"找到{len(elements)}个链接")driver.quit()

定位技巧

  • 优先使用 ID(唯一且高效)
  • 其次考虑 Name 或 Class Name
  • 复杂场景使用 CSS 选择器或 XPath
  • XPath 功能强大但性能相对较差

3. 常用元素操作

Selenium 提供了丰富的方法来操作页面元素:

from selenium import webdriver
from selenium.webdriver.common.by import By
import timedriver = webdriver.Chrome()
driver.get("https://www.example.com/form")# 文本输入框操作
input_field = driver.find_element(By.ID, "username")
input_field.clear()  # 清空输入框
input_field.send_keys("testuser")  # 输入文本
print("输入框内容:", input_field.get_attribute("value"))  # 获取输入内容# 按钮操作
submit_button = driver.find_element(By.ID, "submit-btn")
submit_button.click()  # 点击按钮
# submit_button.submit()  # 表单提交(仅适用于表单元素)# 复选框操作
checkbox = driver.find_element(By.ID, "agree-terms")
if not checkbox.is_selected():  # 判断是否选中checkbox.click()  # 选中复选框# 下拉菜单操作
from selenium.webdriver.support.ui import Select
select_element = Select(driver.find_element(By.ID, "country"))
select_element.select_by_visible_text("China")  # 通过可见文本选择
# select_element.select_by_value("cn")  # 通过value属性选择
# select_element.select_by_index(2)  # 通过索引选择# 获取元素信息
link = driver.find_element(By.LINK_TEXT, "关于我们")
print("链接文本:", link.text)  # 获取元素文本
print("链接地址:", link.get_attribute("href"))  # 获取属性值
print("元素是否可见:", link.is_displayed())  # 判断元素是否可见time.sleep(2)
driver.quit()

三、等待机制

在 Web 自动化中,页面元素加载需要时间,直接操作可能导致元素未找到错误。Selenium 提供了三种等待机制:

1. 隐式等待

设置全局等待时间,对所有元素查找操作生效:

driver = webdriver.Chrome()
driver.implicitly_wait(10)  # 隐式等待10秒

2. 显式等待

针对特定元素设置等待条件和超时时间:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutExceptiondriver = webdriver.Chrome()
driver.get("https://www.example.com/ajax-content")try:# 等待元素出现,最多等10秒,每500毫秒检查一次element = WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located((By.ID, "dynamic-content")))print("找到动态加载的元素:", element.text)# 其他常用条件# EC.visibility_of_element_located: 元素可见# EC.element_to_be_clickable: 元素可点击# EC.text_to_be_present_in_element: 元素包含特定文本except TimeoutException:print("超时:未找到元素")
finally:driver.quit()

3. 强制等待

直接使用 time.sleep() 暂停执行,不推荐频繁使用:

import time
time.sleep(3)  # 强制等待3秒

四、浏览器控制

Selenium 可以控制浏览器的各种行为:

from selenium import webdriver
import timedriver = webdriver.Chrome()# 打开网页
driver.get("https://www.baidu.com")# 窗口操作
driver.maximize_window()  # 最大化窗口
# driver.set_window_size(1024, 768)  # 设置窗口大小
# driver.set_window_position(100, 100)  # 设置窗口位置# 页面操作
driver.get("https://www.google.com")  # 访问新页面
driver.back()  # 后退到上一页
time.sleep(1)
driver.forward()  # 前进到下一页
time.sleep(1)
driver.refresh()  # 刷新页面# 处理多窗口
original_window = driver.current_window_handle  # 记录当前窗口
driver.find_element(By.LINK_TEXT, "新窗口打开").click()  # 打开新窗口# 切换到新窗口
for window_handle in driver.window_handles:if window_handle != original_window:driver.switch_to.window(window_handle)breakprint("新窗口标题:", driver.title)# 关闭当前窗口
driver.close()# 切回原始窗口
driver.switch_to.window(original_window)# 页面截图
driver.save_screenshot("screenshot.png")  # 保存截图# 获取页面信息
print("页面标题:", driver.title)
print("当前URL:", driver.current_url)
# print("页面源码:", driver.page_source)  # 获取页面HTML源码time.sleep(2)
driver.quit()  # 关闭所有窗口并退出

五、实战案例:用户注册功能测试

下面是一个完整的用户注册功能测试案例,结合了 pytest 框架:

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import random
import stringclass TestUserRegistration:"""用户注册功能测试类"""def setup_class(self):"""所有测试开始前执行一次"""self.driver = webdriver.Chrome()self.driver.implicitly_wait(10)self.driver.maximize_window()self.registration_url = "https://example.com/register"def teardown_class(self):"""所有测试结束后执行一次"""self.driver.quit()def setup_method(self):"""每个测试方法开始前执行"""self.driver.get(self.registration_url)def generate_random_email(self):"""生成随机邮箱地址"""random_str = ''.join(random.choices(string.ascii_lowercase + string.digits, k=8))return f"test_{random_str}@example.com"def test_successful_registration(self):"""测试成功注册流程"""# 填写注册表单self.driver.find_element(By.ID, "username").send_keys("testuser123")self.driver.find_element(By.ID, "email").send_keys(self.generate_random_email())self.driver.find_element(By.ID, "password").send_keys("Test@123456")self.driver.find_element(By.ID, "confirm_password").send_keys("Test@123456")# 同意条款并提交self.driver.find_element(By.ID, "agree_terms").click()self.driver.find_element(By.ID, "register_btn").click()# 验证注册成功success_message = WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "success-message")))assert "注册成功" in success_message.textassert "/dashboard" in self.driver.current_urldef test_password_mismatch(self):"""测试密码不匹配的情况"""# 填写表单,使密码和确认密码不一致self.driver.find_element(By.ID, "username").send_keys("testuser456")self.driver.find_element(By.ID, "email").send_keys(self.generate_random_email())self.driver.find_element(By.ID, "password").send_keys("Test@123456")self.driver.find_element(By.ID, "confirm_password").send_keys("Different@123")self.driver.find_element(By.ID, "agree_terms").click()self.driver.find_element(By.ID, "register_btn").click()# 验证错误提示error_message = self.driver.find_element(By.ID, "password_error")assert "密码不一致" in error_message.textassert self.registration_url in self.driver.current_urldef test_empty_required_fields(self):"""测试必填字段为空的情况"""# 不填写必填字段,直接提交self.driver.find_element(By.ID, "register_btn").click()# 验证错误提示errors = self.driver.find_elements(By.CLASS_NAME, "error")assert len(errors) >= 3  # 至少有3个必填字段错误assert "用户名不能为空" in [e.text for e in errors]if __name__ == "__main__":pytest.main(["-v", "test_registration.py"])

六、高级技巧:Page Object 模式

Page Object 模式是一种设计模式,将页面元素和操作封装到类中,提高代码复用性和可维护性:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ECclass BasePage:"""基础页面类,封装通用方法"""def __init__(self, driver):self.driver = driverself.base_url = "https://example.com"def find_element(self, locator, timeout=10):"""查找单个元素"""return WebDriverWait(self.driver, timeout).until(EC.presence_of_element_located(locator))def find_elements(self, locator, timeout=10):"""查找多个元素"""return WebDriverWait(self.driver, timeout).until(EC.presence_of_all_elements_located(locator))def click(self, locator, timeout=10):"""点击元素"""self.find_element(locator, timeout).click()def input_text(self, locator, text, timeout=10):"""在输入框中输入文本"""element = self.find_element(locator, timeout)element.clear()element.send_keys(text)def get_text(self, locator, timeout=10):"""获取元素文本"""return self.find_element(locator, timeout).textdef navigate_to(self, path):"""导航到指定路径"""self.driver.get(f"{self.base_url}{path}")class LoginPage(BasePage):"""登录页面类"""# 元素定位器USERNAME_INPUT = (By.ID, "username")PASSWORD_INPUT = (By.ID, "password")LOGIN_BUTTON = (By.ID, "login_btn")ERROR_MESSAGE = (By.CLASS_NAME, "error-message")def __init__(self, driver):super().__init__(driver)self.path = "/login"def load(self):"""加载登录页面"""self.navigate_to(self.path)def login(self, username, password):"""执行登录操作"""self.input_text(self.USERNAME_INPUT, username)self.input_text(self.PASSWORD_INPUT, password)self.click(self.LOGIN_BUTTON)def get_error_message(self):"""获取错误消息"""return self.get_text(self.ERROR_MESSAGE)class DashboardPage(BasePage):"""仪表盘页面类"""# 元素定位器WELCOME_MESSAGE = (By.CLASS_NAME, "welcome-message")LOGOUT_BUTTON = (By.ID, "logout_btn")def __init__(self, driver):super().__init__(driver)self.path = "/dashboard"def get_welcome_message(self):"""获取欢迎消息"""return self.get_text(self.WELCOME_MESSAGE)def logout(self):"""执行登出操作"""self.click(self.LOGOUT_BUTTON)# 使用示例
if __name__ == "__main__":driver = webdriver.Chrome()driver.maximize_window()# 登录流程login_page = LoginPage(driver)login_page.load()login_page.login("testuser", "testpassword")# 验证登录成功dashboard_page = DashboardPage(driver)assert "欢迎回来,testuser" in dashboard_page.get_welcome_message()# 登出dashboard_page.logout()driver.quit()

七、测试报告与持续集成

1. 生成测试报告

使用 pytest-html 插件生成美观的 HTML 报告:

pip install pytest-html
pytest test_registration.py --html=report.html

2. 持续集成配置

在 CI 环境(如 GitHub Actions)中运行 Selenium 测试:

# .github/workflows/selenium-tests.yml
name: Selenium Testson: [push, pull_request]jobs:test:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v2- name: Set up Pythonuses: actions/setup-python@v2with:python-version: '3.9'- name: Install dependenciesrun: |python -m pip install --upgrade pippip install -r requirements.txt- name: Run testsrun: |pytest --html=report.htmlenv:DISPLAY: :99- name: Upload reportuses: actions/upload-artifact@v2if: always()with:name: test-reportpath: report.html

八、常见问题与解决方案

  1. 元素定位不稳定

    解决方案:使用显式等待代替隐式等待、避免使用动态变化的属性(如随机生成的 ID)
  2. 浏览器兼容性问题

    • 解决方案:在不同浏览器中运行测试
    • 使用 WebDriverManager 自动管理驱动版本
  3. 测试执行速度慢

    • 解决方案:使用 pytest-xdist 并行执行测试
    • 减少不必要的强制等待
  4. 验证码处理

    • 解决方案:测试环境中关闭验证码
    • 使用 API 获取测试验证码
    • 与开发团队合作添加测试专用绕过机制

总结

Selenium 是一个功能强大的 Web 自动化测试工具,通过本教程你应该已经掌握了其核心用法:

  • 环境搭建与基础配置
  • 元素定位与操作方法
  • 等待机制的合理使用
  • 浏览器控制技巧
  • 测试框架整合与 Page Object 模式
  • 测试报告与持续集成

自动化测试是一个持续优化的过程,建议在实际项目中不断总结经验,编写可维护、可扩展的测试代码。随着实践的深入,你还可以探索 Selenium Grid 实现分布式测试,以及与其他工具(如 Appium)结合进行移动端测试。

祝你在自动化测试的道路上越走越远!


文章转载自:

http://eoapSMbn.txfxy.cn
http://hNuDFNES.txfxy.cn
http://GATCdP37.txfxy.cn
http://lofHKqbR.txfxy.cn
http://KfQ3E89S.txfxy.cn
http://v4chCrda.txfxy.cn
http://KFIEHTAm.txfxy.cn
http://ZTiR45Hd.txfxy.cn
http://CLT1no1c.txfxy.cn
http://ro6mBdUO.txfxy.cn
http://1DUEocJu.txfxy.cn
http://ptV1qssi.txfxy.cn
http://t07zvG5P.txfxy.cn
http://FHlPlOUI.txfxy.cn
http://mbUMUuJj.txfxy.cn
http://2O2e8NVe.txfxy.cn
http://DSTn69UV.txfxy.cn
http://SnrTTn4Y.txfxy.cn
http://ZCbQd0n3.txfxy.cn
http://P5rPnXAZ.txfxy.cn
http://VAEzZTFc.txfxy.cn
http://NAPTbbyC.txfxy.cn
http://asluvwQ5.txfxy.cn
http://QS3SjwX3.txfxy.cn
http://NVVYW3da.txfxy.cn
http://sbSAnSfo.txfxy.cn
http://Fwmm14DX.txfxy.cn
http://78p9OIy5.txfxy.cn
http://0IGZWc6x.txfxy.cn
http://AUvBMeG7.txfxy.cn
http://www.dtcms.com/a/384685.html

相关文章:

  • 树莓派4B实现网络电视详细指南
  • Docker:在Windows上安装和使用,加速容器应用开发
  • Android中怎么使用C动态库
  • Redis 安装实战:在 CentOS 中通过源码包安装
  • 抛砖引玉:神经网络的激活函数在生活中也有
  • Java生成与解析大疆无人机KMZ航线文件
  • Mysql 主从复制、读写分离
  • Linux网络设备驱动结构
  • 第四阶段C#通讯开发-3:串口通讯之Modbus协议
  • 使用生成式 AI 和 Amazon Bedrock Data Automation 处理大规模智能文档
  • 可可图片编辑 HarmonyOS(7)图片绘画
  • django登录注册案例(上)
  • 查看iOS设备文件管理 访问iPhone用户文件、App沙盒目录 系统日志与缓存
  • 基于Echarts+HTML5可视化数据大屏展示-白茶大数据溯源平台V2
  • android 框架—网络访问Okhttp
  • CUDA 中Thrust exclusive_scan使用详解
  • Quat 四元数库使用教程:应用场景概述
  • GitHub 热榜项目 - 日榜(2025-09-15)
  • 让AI数据中心突破性能极限
  • Self-supervised Feature Adaptation for 3D Industrial Anomaly Detection 论文精读
  • 【3D图像算法技术讨论】如何给基于3dgs重建的城市街景增加碰撞的属性,满足仿真的要求?
  • numpy学习笔记
  • Oracle体系结构-归档日志文件(Archive Log Files)
  • 唐源电气:机器视觉与AI Agent引领智能运维
  • 【Python】在pycharm中使用environment.ylm文件配置虚拟环境
  • 2025前端面试题及答案-2(详细)
  • 技术突破:《Light Sci. Appl.》SH-GSL理论,为超表面提供全通道谐波调控能力
  • 2025年ASOC SCI2区TOP,多类别教学优化算法+多修剪机器人与多施肥无人机协同任务分配,深度解析+性能实测
  • 佰力博检测与您探讨高低温介电测试的应用领域
  • 网络编程-day6