DeepSeek+Selenium:AI驱动UI自动化测试脚本生成实战
1. 项目概述:当Selenium遇上DeepSeek
最近在搞UI自动化测试的朋友,估计都绕不开一个痛点:写脚本太费劲了。尤其是面对那些频繁迭代、页面元素动来动去的Web应用,维护一整套Selenium测试用例,简直是个体力活加脑力活。定位元素、处理等待、组织断言逻辑……每一个步骤都得手动敲代码,调试起来更是耗时耗力。我自己带团队做自动化测试也有年头了,从最早的录制回放工具,到后来基于Page Object Model(POM)的框架,一直在寻找能提升脚本编写效率的“银弹”。
直到我开始尝试将大语言模型(LLM)引入这个工作流,特别是DeepSeek这类代码生成能力突出的模型,整个局面才豁然开朗。这个项目的核心,就是探索如何用DeepSeek来辅助甚至部分替代人工,生成高质量、可维护的Selenium UI自动化测试脚本。它解决的不仅仅是“写代码”的问题,更是“如何更快地应对需求变化”、“如何降低自动化测试的入门和维护门槛”的问题。无论你是刚接触Selenium的新手,苦于不知从何写起;还是经验丰富的测试开发,被海量的脚本维护工作压得喘不过气,这套结合了AI的自动化方案,都能给你带来实实在在的效率提升。简单来说,这就是用AI的“脑”来理解测试需求,用Selenium的“手”来执行操作,两者结合,让UI自动化测试变得更智能、更轻松。
2. 核心思路与方案选型背后的考量
2.1 为什么是DeepSeek+Selenium这个组合?
选择DeepSeek来赋能Selenium,而不是其他AI工具或测试框架,是经过一番权衡的。首先,Selenium作为Web UI自动化的“事实标准”,其生态成熟、社区活跃、浏览器兼容性好,是绝大多数团队的首选。它的痛点在于脚本编写和维护成本高,而这正是生成式AI的强项。
DeepSeek模型在代码生成和理解方面表现突出,特别是对Python、Java等Selenium常用语言的支持很好。它能够理解用自然语言描述的测试步骤(例如:“打开百度首页,在搜索框输入‘DeepSeek’,点击搜索按钮,并验证结果页面包含‘深度求索’公司链接”),并将其转化为结构化的Selenium代码。相比其他一些通用聊天机器人,DeepSeek在技术代码的生成上更加精准和符合编程规范。
另一个关键考量是 成本与可控性 。虽然市面上有一些宣称“零代码”的自动化测试平台,但它们往往封闭、昂贵,且生成的脚本可移植性和可调试性差。采用DeepSeek + 本地Selenium框架的方案,脚本完全掌握在自己手中,可以轻松集成到现有的CI/CD流水线(如Jenkins, GitLab CI)中,也方便进行版本管理。DeepSeek提供了API接口,也可以部署在本地,数据安全性和调用灵活性都更有保障。
2.2 整体工作流设计
我们的目标不是创造一个完全取代测试工程师的“黑盒”,而是打造一个“AI辅助编程”的高效工作流。这个工作流的核心闭环如下:
- 需求输入 :测试人员用自然语言或结构化的用例描述(Gherkin语言等)定义测试场景。
- AI生成 :将测试描述、目标网页的URL或部分HTML片段(用于元素定位参考)作为提示词(Prompt)提交给DeepSeek。
- 代码输出与审查 :DeepSeek生成初步的Selenium脚本(通常是Python + pytest/unittest格式)。
- 人工润色与集成 :测试开发人员对生成的代码进行审查、调试(如调整元素定位器、优化等待策略)、补充断言逻辑,并将其集成到现有的测试框架中。
- 执行与反馈 :运行脚本,将失败或执行中的问题(如元素未找到、超时)作为新的反馈输入给DeepSeek,进行迭代优化。
这个过程中,人的角色从“代码编写者”转变为“需求定义者”和“代码审查优化者”,把重复性的编码劳动交给AI,从而聚焦于更重要的测试设计、边界案例分析和结果验证上。
注意 :切勿期望AI一次生成完美无缺、可直接生产的脚本。它生成的是一份高质量的“草稿”,能解决70%-80%的基础代码,剩下的20%-30%需要依赖你的领域知识和经验去打磨。这恰恰是效率提升的关键——从0到70%的耗时被极大缩短。
3. 环境搭建与核心工具链配置
3.1 基础环境准备
工欲善其事,必先利其器。首先需要搭建一个稳定可用的工作环境。
Python环境 :建议使用Python 3.8及以上版本。使用 venv 或 conda 创建独立的虚拟环境是最佳实践,可以避免包依赖冲突。
# 创建虚拟环境
python -m venv .venv
# 激活虚拟环境 (Windows)
.venv\Scripts\activate
# 激活虚拟环境 (MacOS/Linux)
source .venv/bin/activate
Selenium安装 :通过pip安装Selenium库以及常用的WebDriver管理器。
pip install selenium webdriver-manager
webdriver-manager 这个包非常实用,它能自动下载和管理对应浏览器版本的WebDriver,省去了手动下载和配置PATH的麻烦。
浏览器驱动 :虽然 webdriver-manager 可以自动处理,但了解其原理很重要。Selenium通过WebDriver与浏览器通信。你需要确保本地安装了Chrome或Firefox浏览器。运行脚本时, webdriver-manager 会自动匹配版本并下载驱动。
3.2 DeepSeek接入方式选择与配置
如何让DeepSeek为我们服务?主要有两种方式:
方式一:通过官方API调用(推荐用于生产或频繁调用) 这是最直接、最稳定的方式。你需要:
- 前往DeepSeek平台注册账号并创建API Key。
- 在代码中安装OpenAI SDK(DeepSeek兼容OpenAI API格式)。
pip install openai
- 在代码或环境变量中配置API Key和Base URL。
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ.get("DEEPSEEK_API_KEY"), # 建议将API Key设为环境变量
base_url="https://api.deepseek.com" # DeepSeek的API端点
)
方式二:本地部署模型(推荐用于数据敏感或离线场景) 如果你对数据隐私要求极高,或者希望拥有完全离线的能力,可以考虑在本地部署DeepSeek的开源模型(如DeepSeek-Coder)。这需要一定的GPU硬件资源和部署知识,通常使用 ollama 、 vLLM 或 Transformers 库来实现。这种方式初期配置复杂,但后期调用无网络依赖、无费用。
# 例如使用ollama部署
ollama pull deepseek-coder:6.7b
ollama run deepseek-coder:6.7b
部署后,API的 base_url 则指向本地服务地址(如 http://localhost:11434/v1 )。
对于大多数团队,我 强烈推荐先从方式一(官方API)开始 。它免去了部署的烦恼,性能稳定,成本可控(按Token计费),可以快速验证想法并投入实际使用。等整个工作流跑通并产生明确价值后,再根据需要考虑是否迁移到本地部署。
3.3 辅助工具:Playwright与Selenium IDE的定位
在热搜词里也看到了Playwright和Selenium IDE。这里简单厘清一下它们在我们的工作流中的角色:
- Playwright :是Selenium的一个强大竞争对手,由微软开发,同样支持多浏览器,并且在自动等待、录制、跨语言支持上有其优势。我们的AI生成思路同样适用于Playwright。你可以将Prompt中的“Selenium”替换为“Playwright”,DeepSeek也能生成对应的代码。选择哪个取决于你们团队的技术栈偏好。
- Selenium IDE :是一个浏览器插件,主要用于录制和回放操作。它生成的脚本通常比较脆弱,不易维护。但在我们的工作流中,它可以作为一个 快速获取元素定位器 的辅助工具。你可以用IDE录制几个关键步骤,然后导出脚本,从中复制复杂的CSS选择器或XPath,再将这些信息作为上下文提供给DeepSeek,能提高生成代码的准确性。
4. 核心:设计高效Prompt与生成脚本
4.1 Prompt工程是成败的关键
AI生成代码的质量,几乎完全取决于你给的Prompt(提示词)。给AI模糊的指令,只能得到模糊甚至错误的代码。一个好的Prompt应该包含以下几个部分:
- 角色设定 :告诉AI它应该扮演什么角色。
- 任务目标 :清晰、分步骤地描述测试场景。
- 技术约束 :指定编程语言、测试框架、代码风格。
- 上下文信息 :提供目标网页的URL、关键元素的HTML片段或选择器。
- 输出格式 :明确要求输出的代码结构。
一个反面例子(过于模糊) :
“帮我写一个登录测试。”
一个正面例子(结构化Prompt) :
你是一个资深的测试开发工程师,擅长编写稳健、可维护的Selenium UI自动化测试脚本。
请使用Python语言,基于pytest框架和Page Object Model (POM) 设计模式,为以下测试场景生成代码。
测试场景:测试用户登录功能
前置条件:用户已注册,账号为 testuser@example.com,密码为 Test123456
测试步骤:
1. 打开登录页面 (https://www.example.com/login)
2. 在“邮箱”输入框中输入注册的邮箱。
3. 在“密码”输入框中输入密码。
4. 点击“登录”按钮。
5. 验证登录成功:检查页面是否跳转到用户仪表盘 (https://www.example.com/dashboard),并且顶部导航栏显示用户名“testuser”。
技术要求:
- 使用显式等待(WebDriverWait)来确保元素可交互。
- 使用相对稳健的定位方式,优先使用ID,其次使用CSS Selector,避免使用绝对XPath。
- 将页面元素定位信息集中管理在Page类中。
- 生成的测试函数应该包含清晰的断言。
请直接输出完整的Python代码文件,包含必要的import语句、Page类和测试函数。
可以看到,清晰的Prompt能引导AI生成出结构良好、考虑了等待和定位策略的工业级代码雏形。
4.2 代码生成与初步审查
将上述Prompt发送给DeepSeek API后,你会得到一份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
class LoginPage:
def __init__(self, driver):
self.driver = driver
self.wait = WebDriverWait(driver, 10)
# 定位器
EMAIL_INPUT = (By.ID, "email") # 假设登录页邮箱输入框的ID是'email'
PASSWORD_INPUT = (By.ID, "password")
LOGIN_BUTTON = (By.CSS_SELECTOR, "button[type='submit']")
USERNAME_SPAN = (By.CLASS_NAME, "username-display") # 假设登录后显示用户名的元素
def enter_email(self, email):
email_field = self.wait.until(EC.element_to_be_clickable(self.EMAIL_INPUT))
email_field.clear()
email_field.send_keys(email)
def enter_password(self, password):
password_field = self.wait.until(EC.element_to_be_clickable(self.PASSWORD_INPUT))
password_field.clear()
password_field.send_keys(password)
def click_login(self):
login_btn = self.wait.until(EC.element_to_be_clickable(self.LOGIN_BUTTON))
login_btn.click()
def get_username_text(self):
return self.wait.until(EC.visibility_of_element_located(self.USERNAME_SPAN)).text
@pytest.fixture(scope="function")
def driver():
driver = webdriver.Chrome()
driver.maximize_window()
yield driver
driver.quit()
def test_user_login(driver):
login_page = LoginPage(driver)
driver.get("https://www.example.com/login")
login_page.enter_email("testuser@example.com")
login_page.enter_password("Test123456")
login_page.click_login()
# 验证URL跳转
WebDriverWait(driver, 10).until(EC.url_to_be("https://www.example.com/dashboard"))
assert driver.current_url == "https://www.example.com/dashboard"
# 验证用户名显示
assert login_page.get_username_text() == "testuser"
print("登录测试通过!")
初步审查要点 :
- 结构检查 :是否采用了POM模式?定位器是否与页面对象分离?
- 定位器检查 :AI生成的定位器(如
By.ID, "email")是否真实存在?这需要你对照实际页面进行核实。这是AI最容易出错的地方。 - 等待策略 :是否合理使用了显式等待?等待时间(如10秒)是否合适?
- 断言逻辑 :断言是否充分且正确?除了URL,是否还需要验证其他元素?
- 健壮性 :代码中是否有必要的清理操作(如
clear())?是否处理了可能的异常?
4.3 从单点生成到流程集成
单个测试脚本的生成只是第一步。在实际项目中,我们需要管理成百上千个测试用例。这就需要将AI生成能力集成到更广泛的流程中。
思路一:基于测试用例管理工具集成 如果你的测试用例是用Excel、TestRail、Xray或甚至写在Confluence Wiki里,可以编写一个脚本,定期读取这些用例描述,批量调用DeepSeek API生成脚本框架,然后由工程师集中审查和入库。这能极大提升从用例设计到脚本实现的转化速度。
思路二:开发IDE插件或CLI工具 你可以开发一个VSCode插件或命令行工具,让工程师在编写测试用例描述文件(如 .feature 文件)时,一键将当前场景发送给DeepSeek,并把生成的代码插入到合适的位置。这提供了更流畅的开发者体验。
思路三:与“测试脚本脚手架”结合 先由AI生成基础的、通用的Page Object和工具类(如浏览器工厂、数据驱动装饰器),然后工程师在这些高质量的基础上,使用AI快速填充具体的测试方法。这样既能保证项目架构的统一,又能发挥AI在填充细节上的效率优势。
5. 生成脚本的优化与调试实战
5.1 常见问题与人工干预点
AI生成的代码很少能直接完美运行。以下是我在实践中总结的几个最常见的需要人工干预的点,以及解决方法:
问题1:元素定位器失效 这是头号问题。AI可能根据你提供的过时HTML片段或通用模式猜测定位器,但实际页面可能使用了动态ID、复杂的CSS类或Shadow DOM。
- 解决方案 :
- 提供更精准的上下文 :在Prompt中直接提供从浏览器开发者工具复制的精确CSS选择器或XPath。
- 使用组合定位器 :教AI使用更稳健的定位方式,例如
By.XPATH, "//button[contains(text(), '登录')]"或By.CSS_SELECTOR, "form.login-form input[name='email']"。 - 事后手动更新 :运行脚本失败后,根据错误信息(如
NoSuchElementException)手动在页面上找到正确元素,更新Page类中的定位器。
问题2:等待策略不足或过度 AI可能会生成固定的 sleep 语句,或者显式等待的条件不对。
- 解决方案 :
- 替换
sleep:将所有time.sleep()替换为针对特定条件的显式等待(WebDriverWait+EC)。 - 调整等待条件 :
element_to_be_clickable适用于按钮点击,visibility_of_element_located适用于检查元素出现,presence_of_element_located要求更低。根据场景选择。 - 动态等待时间 :对于网络环境差或页面加载慢的应用,可以适当增加超时时间,或使用
expected_conditions的复数形式(如visibility_of_all_elements_located)等待一组元素。
- 替换
问题3:缺乏必要的断言或断言过于脆弱 AI可能只生成一个简单的页面标题或URL断言,忽略了业务逻辑验证。
- 解决方案 :
- 补充业务断言 :在关键操作后,添加对页面状态、数据库记录(需连接数据库)、API响应(需结合requests库)或UI元素内容的断言。
- 使用更健壮的断言 :避免断言绝对文本,可以使用
assert ... in ...或assertEqual来检查部分内容。对于列表排序、数值计算等,使用相应的断言方法。
问题4:代码结构不符合项目规范 AI生成的代码风格(如命名习惯、导入顺序、注释风格)可能与你团队的标准不符。
- 解决方案 :
- 在Prompt中明确代码规范要求。
- 使用
black、isort、pylint等代码格式化工具对生成代码进行后处理。 - 将团队约定的
Page基类、BaseTest类模板提供给AI作为参考,让它依葫芦画瓢。
5.2 调试技巧:让AI帮你修复错误
当生成的脚本运行失败时,不要急着全部自己改。可以把错误信息反馈给AI,让它尝试自我修复。
示例Prompt(续写之前的对话或提供新上下文) :
刚才生成的登录测试脚本运行时报错:`selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"button[type='submit']"}`。
我检查了实际页面,登录按钮的HTML是:`<button class="btn btn-primary" data-testid="login-submit">登录</button>`。
请根据这个新的信息,修正LoginPage类中的`LOGIN_BUTTON`定位器,并重新输出完整的Page类代码。
通过这种“执行-报错-反馈-修正”的交互,AI能快速学习你项目的具体细节,后续生成的代码会越来越准。这本质上是在用错误数据对AI进行“微调”。
5.3 参数化与数据驱动测试的生成
一个完整的测试用例往往需要多组数据验证。我们可以指导AI生成参数化测试。
Prompt示例 :
...(同上文角色和约束)...
请为登录功能生成一个参数化测试。使用pytest的`@pytest.mark.parametrize`装饰器。
测试数据如下:
- 正向用例:邮箱 `correct@example.com`, 密码 `CorrectPass123`, 期望结果:登录成功,跳转到/dashboard。
- 反向用例1:邮箱 `wrong@example.com`, 密码 `CorrectPass123`, 期望结果:登录失败,页面显示错误信息“用户不存在或密码错误”。
- 反向用例2:邮箱 `correct@example.com`, 密码 `WrongPass`, 期望结果:登录失败,页面显示错误信息“用户不存在或密码错误”。
请生成包含参数化装饰器和相应断言逻辑的测试函数。
AI会生成一个利用 parametrize 的测试函数,其中包含对成功和失败场景的不同断言,极大提高了测试用例的覆盖率和生成效率。
6. 进阶应用:构建AI增强的自动化测试框架
6.1 封装AI生成层
为了团队协作和统一管理,可以将DeepSeek的调用封装成一个独立的服务或工具类。
# ai_test_generator.py
import openai
import os
from typing import List
class AITestGenerator:
def __init__(self, model="deepseek-chat", api_key=None):
self.client = openai.OpenAI(
api_key=api_key or os.getenv("DEEPSEEK_API_KEY"),
base_url="https://api.deepseek.com"
)
self.model = model
self.system_prompt = """你是一个专业的测试自动化工程师...""" # 系统级角色设定
def generate_test_code(self, test_scenario: str, tech_stack: str, context_html: str = "") -> str:
user_prompt = f"""
技术栈要求:{tech_stack}
测试场景描述:
{test_scenario}
"""
if context_html:
user_prompt += f"""
相关页面元素参考(HTML片段):
{context_html}
"""
response = self.client.chat.completions.create(
model=self.model,
messages=[
{"role": "system", "content": self.system_prompt},
{"role": "user", "content": user_prompt}
],
temperature=0.2, # 较低的温度使输出更确定、更专注于代码
stream=False
)
return response.choices[0].message.content
# 使用示例
generator = AITestGenerator()
code = generator.generate_test_code(
test_scenario="测试商品搜索功能:在首页搜索框输入‘手机’,点击搜索,验证结果列表包含至少一个商品且标题中有‘手机’字样。",
tech_stack="Python, pytest, Selenium, Page Object Model",
context_html='<input type="text" id="search-box" placeholder="搜索商品..."><button id="search-btn">搜索</button>'
)
with open("generated_test_search.py", "w", encoding="utf-8") as f:
f.write(code)
这样,团队成员只需要关注测试场景的描述,而无需关心如何调用AI API。
6.2 生成测试报告与失败分析脚本
AI不仅能生成执行脚本,还能生成辅助脚本。例如,我们可以让AI生成一个简单的测试报告解析脚本,或者在测试失败时自动截屏并记录页面状态的脚本。
Prompt示例 :
请编写一个Python函数,使用Selenium在测试用例失败时自动执行以下操作:
1. 截取当前浏览器窗口的屏幕截图,并以时间戳和测试用例名命名保存。
2. 获取当前页面的URL和标题。
3. 将截图路径、URL、标题和错误信息记录到一个JSON格式的日志文件中。
请将该函数集成到pytest的钩子函数中,以便在测试失败时自动调用。
6.3 面向非技术人员的自然语言测试生成界面
对于测试经理或业务分析师等非技术人员,可以构建一个简单的Web界面或聊天机器人。他们只需在界面中输入类似“我要测试从购物车到支付完成的整个流程”这样的自然语言,后端服务就会调用上述的 AITestGenerator ,生成脚本草稿,并交由测试开发人员审核后加入测试集。这极大地降低了自动化测试的参与门槛。
7. 局限、挑战与未来展望
7.1 当前方案的局限性
尽管DeepSeek+Selenium的组合强大,但我们必须清醒认识其局限:
- 对动态和复杂交互的建模能力有限 :对于需要复杂状态推理、多步骤条件判断(例如:“如果A页面弹出B对话框,则执行C,否则执行D”)的测试流程,AI可能无法一次性生成正确逻辑,需要更细致的人工拆分和指导。
- “视觉”理解能力缺失 :纯代码模型无法“看到”页面。它依赖于你提供的HTML/选择器信息来理解页面结构。对于验证页面布局、颜色、元素相对位置等视觉回归测试(Visual Regression Test),目前仍需专门的工具(如Applitools, Percy)。
- 测试数据与环境的依赖 :AI生成的脚本依赖于特定的测试数据(如登录账号)和环境(如测试服务器URL)。这些需要人工配置和管理,AI无法自动创建测试数据库或部署环境。
- 维护成本转移而非消失 :当页面发生重大改版时,AI生成的定位器会大面积失效。此时,你需要更新Prompt中的上下文信息并重新生成,或者手动修复。维护工作从“改代码”变成了“改Prompt和上下文”,并 没有消失 ,但通常更容易,因为你可以用自然语言描述变化。
7.2 应对挑战的实践心得
- 从小处着手,积累Prompt模板 :不要一开始就试图自动化整个复杂的端到端流程。从单个页面、单个功能(如登录、搜索)开始,积累针对不同操作(输入、点击、下拉选择、拖拽)的Prompt模板和代码片段。这些模板将成为团队的宝贵资产。
- 建立“黄金上下文”库 :为系统的核心页面(如首页、登录页、主功能页)维护一份最新的、包含关键元素定位器的HTML片段或选择器列表。每次需要生成相关测试时,直接附上这份“黄金上下文”,能极大提高生成准确率。
- 人机协同,责任分明 :明确AI的定位是“高级助手”而非“替代者”。测试设计、用例规划、结果分析、复杂逻辑处理,这些需要人类智慧和业务经验的工作,必须由人主导。AI负责执行重复、规范的编码任务。
- 持续迭代Prompt :将生成-运行-调试的过程看作是对你团队专属Prompt的持续训练。记录下哪些描述方式AI理解得好,哪些容易出错,不断优化你的Prompt指令集。
7.3 未来的演进方向
结合最新的技术趋势,这个领域还有更多可能性:
- 多模态模型接入 :未来如果能接入具备屏幕截图分析能力的多模态大模型(如GPT-4V),测试生成将发生革命性变化。你可以直接对截图说:“在这个登录框里输入账号密码”,模型能自己识别元素并生成操作代码,彻底摆脱对HTML上下文的依赖。
- 与无代码/低代码平台结合 :AI生成的标准Selenium/Playwright代码,可以成为连接自然语言需求与可执行脚本的中间层。低代码测试平台可以将其作为底层引擎,提供更友好的可视化界面。
- 自我修复与自适应测试 :结合测试执行结果的反馈,构建一个闭环系统。当测试失败时,系统能自动分析失败原因(是元素变了还是流程变了?),尝试调整定位器或修改流程,并重新生成脚本进行验证,向着“自适应自动化测试”迈进。
- 智能测试用例生成与优化 :不仅生成脚本,还能基于代码变更、用户行为数据,智能推荐需要补充或修改的测试用例,实现测试套件的动态优化,提升测试覆盖率的价值密度。
回过头看,用DeepSeek生成Selenium脚本,其价值远不止是“写代码更快了”。它正在改变测试自动化的工作模式,将测试人员从重复的、机械的编码劳动中解放出来,让他们能更专注于高价值的测试策略设计、用户体验评估和复杂问题排查。这个过程里,最大的体会就是: 最好的工具不是替代你,而是让你变得更像你自己——一个更有创造力、更能思考本质问题的工程师。 一开始可能会觉得调教AI很麻烦,但一旦你和它形成了默契,建立起高效的工作流,你就会发现,你们成了一个配合默契的“超级团队”。
更多推荐

所有评论(0)