基于 Pytest+Selenium 的 DeepSeek 登录功能自动化测试实践
基于 Pytest+Selenium 的 DeepSeek 登录功能自动化测试实践_哔哩哔哩_bilibili。
欢迎来到谢金金的博客,我们测试人员必不可少的测试离不开自动化测试,而自动化测试就会包括python+selenium+pytest的应用,以下是我基于 Pytest+Selenium 的 DeepSeek 登录功能自动化测试实践测试案例,在日常的 Web 应用测试中,登录功能作为用户访问系统的入口,其稳定性和正确性至关重要。本文将以 DeepSeek(深度求索)的登录功能为例,详细介绍如何使用 Pytest 测试框架结合 Selenium 自动化工具,实现登录场景的自动化测试,并生成直观的测试报告。
-
.视频介绍
- 可观看下方链接的实践视频了解
- 基于 Pytest+Selenium 的 DeepSeek 登录功能自动化测试实践_哔哩哔哩_bilibili
一、技术栈选型与环境准备
1. 核心技术栈说明
本次自动化测试方案选用Pytest+Selenium的组合,核心优势如下:
- Pytest:Python 生态中最流行的测试框架之一,支持参数化测试、固件(Fixture)机制,语法简洁且扩展性强,方便批量管理测试用例。
- Selenium:主流的 Web 自动化测试工具,支持多浏览器(Chrome、Firefox 等),能够模拟用户的真实操作(点击、输入、跳转等),适配各类 Web 应用。
- pytest-html:Pytest 的第三方插件,用于生成美观的 HTML 测试报告,便于查看测试结果详情。
2. 环境搭建步骤
(1)安装 Python
确保本地安装 Python 3.7 及以上版本,可通过python --version命令验证版本。
(2)安装依赖包
通过 pip 命令安装所需的第三方库,执行如下命令:
bash
# 安装Pytest
pip install pytest
# 安装Selenium
pip install selenium
# 安装HTML报告插件
pip install pytest-html
(3)配置 Chrome 驱动
Selenium 操作 Chrome 浏览器需要对应版本的 ChromeDriver:
- 查看本地 Chrome 浏览器版本(设置→关于 Chrome);
- 访问ChromeDriver 官网下载匹配版本的驱动;
- 解压后将
chromedriver.exe放入指定目录(如项目下的 “谷歌浏览器驱动” 文件夹)。
二、自动化测试框架设计
本次测试框架遵循 “模块化、可复用” 原则,分为固件层(Fixture)、业务逻辑层(封装操作)、测试用例层(参数化场景) 三层结构,具体设计如下:
| 层级 | 作用 | 核心实现 |
|---|---|---|
| 固件层 | 初始化 / 销毁浏览器,前置页面操作 | Pytest Fixture(函数级作用域) |
| 业务逻辑层 | 封装登录核心操作(输入、点击等) | 自定义 login () 函数 |
| 测试用例层 | 设计多场景测试用例,验证登录结果 | Pytest 参数化 + 断言 |
三、完整代码实现与解析
1. 代码结构
项目代码结构清晰,单个脚本即可完成测试(后续可扩展为多模块项目):
plaintext
deepseek_login_test/
├─ 谷歌浏览器驱动/ # 存放chromedriver.exe
└─ test_deepseek_login.py # 核心测试脚本
2. 完整测试代码
python
运行
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
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.chrome.service import Service
# ---------------------- 1. 固件层:浏览器驱动初始化与前置操作 ----------------------
@pytest.fixture(scope="function")
def driver():
"""
函数级Fixture:每个测试用例前启动浏览器,测试后关闭浏览器
"""
# 初始化Chrome驱动(需确保chromedriver路径正确)
service = Service("./谷歌浏览器驱动/chromedriver.exe")
driver = webdriver.Chrome(service=service)
driver.maximize_window() # 最大化浏览器窗口,避免元素定位受窗口大小影响
driver.get("https://chat.deepseek.com/sign_in") # 打开DeepSeek登录页
# 步骤1:等待并点击"密码登录"选项卡(默认可能是"验证码登录")
try:
password_login_tab = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH,
'//*[@id="root"]/div/div/div[2]/div/div/div[2]/div[1]/div[1]/div[2]/div[1]'))
)
password_login_tab.click()
print("✅ 已切换到密码登录选项卡")
except TimeoutException:
print("❌ 超时:未找到密码登录选项卡,测试终止")
driver.quit()
return
# 步骤2:验证登录表单是否加载完成(以用户名输入框为例)
try:
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR,
"#root > div > div > div._99ad066 > div > div > div.ds-sign-up-form__main > div.ds-sign-up-form__main-hero > div:nth-child(3) > div.ds-form-item__content > div > input"))
)
print("✅ 登录表单加载完成")
except TimeoutException:
print("❌ 超时:登录表单加载失败,测试终止")
driver.quit()
return
yield driver # 传递驱动给测试用例
driver.quit() # 测试用例执行完毕后关闭浏览器
print("\n✅ 浏览器已关闭")
# ---------------------- 2. 业务逻辑层:封装登录操作 ----------------------
def login(driver, username, password):
"""
登录操作封装:输入用户名、密码,点击登录按钮
:param driver: 浏览器驱动对象
:param username: 登录手机号
:param password: 登录密码
"""
# 输入用户名(手机号)
user_input = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR,
"#root > div > div > div._99ad066 > div > div > div.ds-sign-up-form__main > div.ds-sign-up-form__main-hero > div:nth-child(3) > div.ds-form-item__content > div > input"))
)
user_input.clear() # 清空输入框(避免默认提示文本干扰)
user_input.send_keys(username)
print(f"📱 已输入用户名:{username if username else '空'}")
# 输入密码
pwd_input = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR,
"#root > div > div > div._99ad066 > div > div > div.ds-sign-up-form__main > div.ds-sign-up-form__main-hero > div:nth-child(4) > div.ds-form-item__content > div > input"))
)
pwd_input.clear()
pwd_input.send_keys(password)
print(f"🔑 已输入密码:{'*' * len(password) if password else '空'}")
# 点击登录按钮
login_btn = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR,
"#root > div > div > div._99ad066 > div > div > div.ds-sign-up-form__main > div.ds-sign-up-form__main-hero > div.ds-button.ds-button--primary.ds-button--filled.ds-button--rect.ds-button--block.ds-button--l.ds-sign-up-form__register-button"))
)
login_btn.click()
print("🔘 已点击登录按钮")
# ---------------------- 3. 测试用例层:参数化测试场景 ----------------------
@pytest.mark.parametrize(
"case_name, username, password, expected",
[
("场景1:正确账号密码登录", "15303054272", "3105952423", "登录成功"),
("场景2:错误账号登录", "13800000000", "Test123456", "账号或密码错误"),
("场景3:错误密码登录", "13800138000", "Wrong123", "账号或密码错误"),
("场景4:空账号登录", "", "Test123456", "请输入手机号"),
("场景5:空密码登录", "13800138000", "", "请输入密码"),
("场景6:无效格式账号登录", "invalid-phone", "Test123456", "请输入正确的手机号")
]
)
def test_deepseek_login(driver, case_name, username, password, expected):
"""
DeepSeek登录测试用例(参数化覆盖6种核心场景)
"""
if not driver: # 若驱动初始化失败,直接跳过测试
pytest.skip("驱动初始化失败,跳过测试用例")
print(f"\n==================== 开始测试:{case_name} ====================")
# 执行登录操作
login(driver, username, password)
# 结果验证:分"错误提示"和"登录成功"两种情况判断
try:
# 情况1:预期为错误提示(如空账号、格式错误等)
error_msg = WebDriverWait(driver, 5).until(
EC.presence_of_element_located((By.CSS_SELECTOR, ".error"))
).text
assert expected in error_msg, f"❌ 断言失败:实际提示[{error_msg}],预期包含[{expected}]"
print(f"✅ 测试通过:{case_name}(错误提示符合预期)")
except:
# 情况2:预期为登录成功(通过"聊天输入框"是否出现判断)
try:
WebDriverWait(driver, 15).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "#chat-input"))
)
assert "登录成功" in expected, f"❌ 断言失败:预期[{expected}],但实际登录成功"
print(f"✅ 测试通过:{case_name}(成功进入聊天页面)")
except TimeoutException:
print(f"❌ 测试失败:{case_name},未检测到错误提示且未进入聊天页面")
3. 核心代码解析
(1)固件层(Fixture):driver()函数
- 作用域:
scope="function"表示每个测试用例都会重新启动浏览器,避免用例间的状态干扰; - 显式等待:使用
WebDriverWait+expected_conditions替代time.sleep(),等待元素 “可点击” 或 “存在” 后再操作,提高测试稳定性; - 异常处理:若前置操作(如切换登录选项卡)超时,直接关闭浏览器并终止测试,避免无效执行。
(2)业务逻辑层:login()函数
- 封装复用:将 “输入账号 - 输入密码 - 点击登录” 的重复操作封装为函数,减少代码冗余;
- 元素定位:结合
CSS_SELECTOR和XPATH定位元素,优先选择稳定性高的CSS_SELECTOR(如基于类名、ID 的定位)。
(3)测试用例层:test_deepseek_login()函数
- 参数化测试:通过
@pytest.mark.parametrize一次性传入 6 种场景的测试数据,无需编写 6 个重复的用例函数; - 结果断言:分两种情况验证结果:
- 错误场景:断言页面是否出现预期的错误提示(如 “请输入手机号”);
- 成功场景:断言是否加载出登录后的 “聊天输入框”,确认登录成功。
四、测试执行与报告生成
1. 执行测试命令
在项目根目录下打开终端,执行如下命令启动测试并生成 HTML 报告:
bash
pytest test_deepseek_login.py -v --html=deepseek_login_report.html
-v:显示详细的测试日志(如用例名称、执行结果);--html=deepseek_login_report.html:指定 HTML 报告的文件名和路径。
2. 执行过程说明
运行命令后,Chrome 浏览器会自动启动并依次执行 6 个测试场景:
- 每个场景前,Fixture 会初始化浏览器并切换到密码登录页;
- 执行登录操作后,根据预期结果进行断言;
- 每个场景结束后,浏览器自动关闭;
- 所有用例执行完毕后,在项目根目录生成
deepseek_login_report.html报告文件。
3. HTML 报告解读
打开生成的 HTML 报告,可直观查看以下信息:
- 概要:测试用例总数、通过数、失败数、跳过数、执行时长;
- 详细结果:每个用例的名称、状态、执行时间、日志输出;
- 错误详情:若用例失败,会显示断言失败的具体原因(如实际提示与预期不符)。
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)