基于Qwen3.5-9B与OpenClaw的AI驱动UI自动化测试实战
1. 项目概述:当大模型遇上UI自动化测试
最近在搞一个挺有意思的玩意儿,叫OpenClaw。这名字听着挺唬人,其实你可以把它理解成一个“AI驱动的自动化测试大脑”。它的核心玩法,是把像Qwen3.5-9B这样的大语言模型,和传统的UI自动化测试工具(比如Selenium、Playwright、Appium)给“缝合”到了一起。我这次折腾的目标,就是用Qwen3.5-9B这个模型来驱动OpenClaw,让它能自动执行UI回归验证。说白了,就是让AI自己去看网页或者App,然后像人一样去点点按钮、输入文字,最后判断功能是不是正常。
这听起来是不是有点像科幻片?但实际做下来,你会发现它既有令人兴奋的潜力,也有一堆需要填的坑。传统的UI自动化测试,脚本是死的,页面元素一变,脚本就“瞎”了,维护成本高得吓人。而大模型的优势在于它的“理解”能力,它能看懂页面上的文字、理解按钮的意图,甚至能处理一些简单的逻辑判断。比如,你告诉它“去登录页面,用账号test@example.com和密码123456登录”,它就能自己找到用户名输入框、密码输入框和登录按钮,并完成操作。这对于应对频繁变化的UI,或者快速验证核心业务流程,提供了一个全新的思路。
这个项目适合谁呢?首先肯定是测试开发工程师和对测试前沿技术感兴趣的朋友。其次,对于想探索大模型在具体业务场景(RPA、智能助手)落地的开发者,这也是一个绝佳的练手项目。当然,你需要对Python、基本的命令行操作,以及UI自动化测试有初步了解。整个过程,我会带你从零开始,把环境搭起来,把模型跑起来,最后让AI真正动起来去测试一个真实的网页。过程中踩过的坑、调优的参数,我都会毫无保留地分享出来。
2. 核心思路与架构拆解:为什么是OpenClaw + Qwen3.5-9B?
在动手之前,我们得先搞清楚这套组合拳背后的逻辑。为什么选OpenClaw?又为什么是Qwen3.5-9B?这直接决定了我们后续实践的效率和天花板。
2.1 OpenClaw:不只是另一个测试框架
OpenClaw的定位很清晰,它是一个 大模型驱动的智能体(Agent)框架 ,专门为自动化操作而生。它不是一个要取代Selenium或Playwright的底层工具,而是站在它们肩膀上的“指挥官”。你可以把它想象成一个拥有“眼睛”(页面截图/HTML解析)和“大脑”(大语言模型),但“手”和“脚”还是Selenium/Playwright的智能体。
它的工作流程通常是这样的:
- 观察 :OpenClaw通过底层驱动(如Playwright)获取当前页面的状态。这个状态可以是截屏图片,也可以是结构化的HTML/DOM信息,或者两者都有。
- 思考 :它将当前页面状态、历史操作记录以及你的自然语言指令(例如:“点击登录按钮”)一起,打包成一个精心设计的提示词(Prompt),发送给大模型(如Qwen3.5-9B)。
- 决策 :大模型分析提示词后,输出一个结构化的动作指令。这个指令不是简单的“click”,而可能是
{"action": "click", "selector": "button:has-text('登录')", "reason": "根据指令,需要点击登录按钮以进入下一步"}。 - 执行 :OpenClaw解析这个动作指令,调用对应的底层API(如Playwright的
page.click(selector))来执行操作。 - 循环 :然后回到步骤1,观察操作后的新页面状态,继续下一步决策,形成一个闭环。
这种架构的优势在于 将变化的UI逻辑从脆硬的代码脚本中解耦出来,交给了具有理解能力的大模型 。按钮的文本从“登录”变成“Sign In”,只要模型能看懂,它就能找到。页面结构微调,只要关键元素还在,模型就有可能通过上下文推断出来。这大大提升了自动化脚本的健壮性和可维护性。
2.2 模型选型:为什么是Qwen3.5-9B?
市面上开源模型那么多,为什么我这次重点用Qwen3.5-9B?这背后是性能、成本、易用性和中文能力的综合权衡。
- 性能与成本的平衡 :Qwen3.5-9B拥有90亿参数,在同类尺寸模型中,其推理能力、代码能力和指令跟随能力都相当出色。对于UI自动化这种需要精确理解指令和页面元素的任务,7B以下的模型可能显得力不从心,而70B级别的模型虽然更强,但对本地部署的硬件要求(需要多张高端显卡)和推理速度都是巨大挑战。9B这个级别,在一张消费级显卡(如RTX 3090/4090)上就能流畅运行,是性价比极高的选择。
- 出色的中文与代码能力 :通义千问团队在中文语料和代码数据上进行了充分训练,这使得Qwen3.5-9B在处理中文界面和生成结构化操作指令(本质上是代码或JSON)时,表现比同尺寸的许多国际模型更稳定、更准确。我们的测试场景很多都是中文网站,这一点至关重要。
- 本地化部署与隐私 :通过Ollama、LM Studio等工具,我们可以轻松地在本地或内网部署Qwen3.5-9B。这意味着所有的页面数据、操作指令都不会离开你的环境,对于测试企业内部系统或涉及敏感数据的应用,这是必须满足的安全要求。
- 关于速度的坑 :网络热词里提到了“qwen3.5-9b 在omlx回复非常慢”。这是一个非常实际的痛点。Ollama默认的配置可能未针对速度做极致优化。慢的原因可能包括:模型未量化(占用显存大,计算慢)、没有使用GPU加速、或者Prompt设计不当导致模型“思考”过久。在后续的配置章节,我会详细讲解如何通过量化、选用合适的推理后端(如
vLLM)等技巧,把推理速度提上来,确保测试执行的效率。
所以,我们的技术栈就明确了:OpenClaw作为智能体框架,Qwen3.5-9B作为决策大脑,Playwright作为执行手脚。 接下来,我们就开始动手搭建这个“数字测试员”。
3. 环境准备与核心配置实战
这一部分是实战的起点,也是最容易卡住的地方。我会尽量详细地列出每一步,特别是针对不同操作系统(Windows/macOS/Linux)的差异和常见坑点。
3.1 基础Python环境搭建
首先需要一个干净的Python环境,强烈建议使用 conda 或 venv 创建虚拟环境,避免包冲突。
# 使用 conda 创建环境(推荐)
conda create -n openclaw-test python=3.10
conda activate openclaw-test
# 或者使用 venv
python -m venv openclaw-env
# Windows
openclaw-env\Scripts\activate
# Linux/macOS
source openclaw-env/bin/activate
3.2 安装OpenClaw与Playwright
OpenClaw可以通过pip直接安装。注意,它可能会依赖较新版本的某些库。
pip install openclaw
安装完成后,安装Playwright的浏览器驱动。OpenClaw底层默认使用Playwright,所以这一步必不可少。
# 安装Playwright的Python库
pip install playwright
# 安装Chromium, Firefox, WebKit浏览器内核(主要用Chromium)
playwright install chromium
注意 :
playwright install命令会下载浏览器二进制文件,体积较大(约几百MB),请确保网络通畅。如果在内网环境,可以提前下载好对应版本的浏览器,通过设置环境变量指定路径。
3.3 部署Qwen3.5-9B:Ollama方案详解
这是核心环节。为了让OpenClaw能调用本地的Qwen3.5-9B,我们需要一个模型服务。Ollama是目前最方便的方案之一。
1. 安装Ollama: 前往Ollama官网下载对应操作系统的安装包。安装过程很简单,一路下一步即可。安装完成后,打开终端,应该能直接运行 ollama 命令。
2. 拉取并运行Qwen3.5-9B模型: Ollama提供了预置的Qwen3.5-9B模型,但为了追求速度,我们拉取量化版本。
# 拉取 4-bit 量化的 Qwen2.5-9B 模型(性能损失小,速度提升明显)
# 注意:Ollama官方库可能叫 qwen2.5:9b 或类似,请以 ollama list 显示为准
# 如果找不到,可以先拉取原版 qwen2.5:9b
ollama pull qwen2.5:9b
# 运行模型服务。默认端口是11434
ollama run qwen2.5:9b
运行后,终端会显示模型加载信息,并进入一个交互式对话界面。这说明模型服务已经在本地的11434端口启动了。
3. 速度优化配置(解决“回复慢”问题): 如果觉得默认速度慢,可以创建自定义的Model File来调整参数。
创建一个名为 Modelfile.qwen9b 的文件,内容如下:
FROM qwen2.5:9b
# 设置更低的温度,让输出更确定、更简洁,适合执行任务
PARAMETER temperature 0.1
# 开启GPU加速(如果支持)
PARAMETER numa
# 如果显存足够,可以设置更高的上下文长度,但可能会影响速度
# PARAMETER num_ctx 4096
然后创建并运行这个自定义模型:
ollama create my-qwen9b-fast -f ./Modelfile.qwen9b
ollama run my-qwen9b-fast
关键技巧:使用 vLLM 后端获得极致速度 如果对速度有极致要求,并且你的显卡是NVIDIA的,可以弃用Ollama,改用 vLLM 部署。 vLLM 是一个高性能推理引擎,吞吐量和延迟表现通常优于Ollama。
# 安装 vLLM
pip install vllm
# 启动 vLLM 服务,托管 Qwen3.5-9B 模型
# 需要提前从Hugging Face下载模型,这里假设模型已下载到本地路径 /path/to/qwen2.5-9b
vllm serve /path/to/qwen2.5-9b-instruct --host 0.0.0.0 --port 8000 --api-key token-abc123 --max-model-len 4096 --tensor-parallel-size 1
启动后,会提供一个OpenAI兼容的API端点( http://localhost:8000/v1 )。之后在OpenClaw配置中,将模型端点指向这里即可。 vLLM 的并发处理能力更强,在批量执行测试任务时优势明显。
3.4 OpenClaw配置:连接大脑与手脚
OpenClaw需要一个配置文件来指定使用哪个模型、哪个执行器。通常配置文件是一个YAML或JSON文件,也可以通过环境变量设置。
创建一个简单的配置文件 config.yaml :
model:
# 使用本地Ollama服务
provider: "openai"
# Ollama提供的API兼容OpenAI,所以这里用openai
api_base: "http://localhost:11434/v1"
model: "qwen2.5:9b"
api_key: "ollama" # Ollama不需要真正的key,但有些框架要求非空,任意字符串即可
temperature: 0.1 # 低温度,输出稳定
agent:
name: "ui_tester"
# 设置执行器为 Playwright
executor: "playwright"
playwright:
headless: true # 无头模式,不显示浏览器窗口
slow_mo: 50 # 每个操作延迟50毫秒,方便观察和录制
viewport: {"width": 1920, "height": 1080}
# 日志配置,方便调试
logging:
level: "INFO"
file: "./openclaw.log"
重要环境变量配置: 有些配置也可以通过环境变量传入,这在CI/CD流水线中更常用。
# Linux/macOS
export OPENCLAW_MODEL_API_BASE="http://localhost:11434/v1"
export OPENCLAW_MODEL_NAME="qwen2.5:9b"
export OPENCLAW_EXECUTOR="playwright"
# Windows (PowerShell)
$env:OPENCLAW_MODEL_API_BASE="http://localhost:11434/v1"
$env:OPENCLAW_MODEL_NAME="qwen2.5:9b"
$env:OPENCLAW_EXECUTOR="playwright"
至此,我们的“数字测试员”的硬件(环境)和基础软件(驱动)就准备就绪了。接下来,我们要教它如何执行具体的测试任务。
4. 编写与执行第一个AI驱动的UI测试用例
现在,让我们用一个实际的例子,看看如何用自然语言指挥OpenClaw完成一个完整的UI操作流程。我们以一个经典的电商网站登录-搜索-加入购物车流程为例。
4.1 测试用例设计:从自然语言到可执行任务
传统的测试脚本需要精确的定位器(XPath, CSS Selector)。现在,我们只需要用自然语言描述任务。OpenClaw会利用大模型将其分解为原子操作。
我们创建一个Python脚本 test_ecommerce_flow.py :
import asyncio
from openclaw import Claw
async def main():
# 初始化Claw智能体,默认会读取我们上面创建的config.yaml或环境变量
claw = Claw()
# 任务描述:用自然语言描述你要测试的完整流程
task_description = """
请测试一个电商网站的购物流程。
1. 打开浏览器,访问 https://demo.ecommerce.com (假设的测试网站)。
2. 在首页的右上角找到并点击“登录”链接。
3. 在登录页面,使用用户名 “test_user@example.com” 和密码 “Test123456” 进行登录。
4. 登录成功后,在首页顶部的搜索框输入 “无线蓝牙耳机”,然后点击搜索按钮或按回车。
5. 在搜索结果列表页面,找到第一个商品,点击进入商品详情页。
6. 在商品详情页,找到“加入购物车”按钮并点击。
7. 点击页面顶部的“购物车”图标,进入购物车页面。
8. 在购物车页面,验证刚才加入的商品“无线蓝牙耳机”是否在列表中。
9. 最后,在购物车页面找到并点击“结算”按钮,进入结算页面即可。
"""
print("开始执行AI驱动的UI测试任务...")
print(f"任务描述:\n{task_description}\n")
try:
# 将任务交给Claw执行
result = await claw.run(task=task_description)
print(f"\n任务执行结果:{result}")
# 你可以进一步解析result,里面包含了每一步的操作日志、成功与否的状态
if result and result.get('success'):
print("✅ 测试流程执行成功!")
else:
print("❌ 测试流程执行失败或未完成。")
print(f"错误信息:{result}")
except Exception as e:
print(f"执行过程中发生异常:{e}")
finally:
# 关闭Claw,释放资源
await claw.close()
if __name__ == "__main__":
asyncio.run(main())
这个脚本的核心就是 claw.run(task_description) 。我们把一段详细的自然语言指令扔进去,剩下的就交给OpenClaw和Qwen3.5-9B了。
4.2 执行与观察:AI如何“思考”和“操作”
运行这个脚本:
python test_ecommerce_flow.py
你会看到终端输出一系列日志,同时(如果你设置了 headless: false )会弹出一个浏览器窗口,自动执行所有操作。观察日志,你会发现OpenClaw在内部做了很多事情:
- 任务规划 :模型首先会理解整个任务,并将其分解成一系列顺序执行的子目标。
- 元素定位 :对于每个子目标(如“点击登录链接”),模型会结合当前的页面截图或DOM,去“寻找”最匹配的元素。它可能通过文本内容(“登录”)、元素类型(
<a>链接)、位置(右上角)等多种特征综合判断。 - 动作生成与执行 :找到元素后,模型生成具体的Playwright操作指令,如
page.click('a:has-text("登录")'),然后执行。 - 状态验证与循环 :执行后,OpenClaw会等待页面加载或状态稳定,然后获取新的页面状态,继续下一个子目标。
实操心得:如何写出更高效的指令
- 指令要具体,但避免过度精确 :说“点击登录按钮”比说“点击那个按钮”好。但不要说“点击ID为
login-btn的按钮”,这又变回了传统自动化,失去了AI理解的优势。让AI去“找”登录按钮。 - 分步骤描述 :像上面的例子一样,用1、2、3列出步骤,有助于模型进行任务分解。
- 提供关键文本 :在指令中包含页面上预期会出现的关键文本(如“登录”、“搜索”、“加入购物车”),这能极大地帮助模型进行定位。
- 设定明确的成功条件 :在任务描述的最后,告诉AI需要验证什么(如“验证商品是否在列表中”),这样AI才知道任务何时算完成。
4.3 断言与结果验证:让测试不只是“走过场”
上面的例子只执行了操作,但自动化测试的灵魂在于“断言”(Assertion)。我们需要验证结果是否符合预期。OpenClaw本身不内置复杂的断言库,但我们可以通过其执行结果和模型的能力来实现。
方法一:利用模型的判断能力进行验证 我们可以在任务描述中,要求模型在关键步骤后“观察”页面并做出判断。
task_description_with_assert = """
... (前面的步骤1-7同上) ...
8. 在购物车页面,请仔细观察页面内容。
9. 如果页面上显示了文字“无线蓝牙耳机”,并且数量是1,请回复“购物车验证成功”。否则,请回复“购物车验证失败,未找到对应商品或数量不对”。
"""
# 执行后,解析claw.run返回的最终结果,检查是否包含“成功”字样。
方法二:结合传统断言库(推荐) 更可靠的方式是,在AI完成关键操作后,我们通过Playwright的API直接获取页面元素进行断言。这需要我们在脚本中混合使用AI指令和传统代码。
async def test_with_hard_assert(claw):
# 1. 用AI完成登录、搜索、加购等前置流程
await claw.run("打开https://demo.ecommerce.com并登录,搜索‘无线蓝牙耳机’并加入购物车,然后进入购物车页面。")
# 2. AI操作完成后,我们拿到当前的Playwright page对象进行精确断言
page = claw.executor.page # 假设executor提供了page对象
# 等待购物车页面特定元素出现
await page.wait_for_selector('text=购物车')
# 使用Playwright的断言API
product_item = page.locator('.cart-item:has-text("无线蓝牙耳机")')
await expect(product_item).to_be_visible()
quantity = page.locator('.cart-item-quantity >> nth=0')
await expect(quantity).to_have_text('1')
print("✅ 硬断言通过:商品已正确加入购物车。")
这种“AI导航 + 传统断言”的混合模式,结合了AI的灵活性和传统断言的可靠性,是目前最实用的策略。
5. 高级技巧与性能调优
当基本流程跑通后,我们会追求更稳定、更快速、更复杂的测试能力。这部分分享一些进阶的实战经验。
5.1 提升稳定性:处理动态元素与等待
AI不是万能的,页面加载慢、动态渲染的元素(如Vue/React组件)、弹窗都会导致操作失败。
- 显式等待策略 :在给AI的指令中,可以加入“等待”的提示。例如:“点击登录按钮, 然后等待页面跳转完成,直到看到‘欢迎回来’的标题 ”。模型在生成下一步动作前,会结合这个提示去判断页面是否就绪。
- 配置Playwright等待参数 :在OpenClaw的配置中,可以调整Playwright的默认等待超时时间。
playwright: timeout: 30000 # 全局超时设为30秒 navigation_timeout: 60000 # 页面导航超时60秒 - 使用Retry机制 :对于重要的操作步骤,可以在外围代码逻辑中实现重试。如果AI某一步失败了(比如没找到元素),捕获异常,让AI重新观察页面再试一次。
5.2 编写可复用的“技能”(Skill)
OpenClaw支持“技能”概念,你可以把常用的复杂操作封装成一个技能,供多个测试用例调用。这类似于传统自动化中的Page Object模式。
创建一个技能文件 login_skill.py :
from openclaw.skill import Skill
class LoginSkill(Skill):
name = "login"
description = "在电商网站使用指定账号密码登录"
async def execute(self, claw, username, password):
task = f"""
请执行登录操作。
1. 如果当前页面有“登录”或“Sign In”链接,请点击它。
2. 在登录表单中,找到用户名输入框,输入:{username}
3. 找到密码输入框,输入:{password}
4. 找到并点击“登录”或“Login”按钮。
5. 等待登录完成,直到页面上出现用户菜单或“我的账户”字样。
"""
return await claw.run(task)
在主测试脚本中调用:
from login_skill import LoginSkill
claw = Claw(skills=[LoginSkill()])
# 直接调用技能,而不是写冗长的自然语言指令
await claw.call_skill("login", username="test@example.com", password="123456")
这样,测试用例的逻辑会更清晰,维护性也更好。
5.3 性能调优:让测试跑得更快
“慢”是大模型应用的核心痛点。除了前面提到的使用量化模型和 vLLM ,还有以下技巧:
- 优化Prompt :给模型的指令要简洁、明确。避免冗长的背景描述。OpenClaw框架本身会组装包含页面信息的Prompt,我们只需关注任务指令本身。
- 降低
temperature:在模型配置中,将temperature设为较低值(如0.1),使模型的输出更确定、更简洁,减少“胡思乱想”的时间。 - 并行执行 :如果测试集庞大,可以考虑使用
asyncio或线程池,同时运行多个Claw实例(每个实例对应一个独立的浏览器上下文),并行执行不同的测试用例。注意管理好模型服务的负载。 - 缓存页面信息 :对于相对静态的页面,可以考虑将AI分析过的页面元素信息(如某个按钮的稳定定位器)缓存下来,下次直接使用,绕过AI分析环节。这需要定制OpenClaw的中间件。
5.4 视觉增强与多模态模型
OpenClaw默认可能主要依赖DOM信息。但对于一些重度依赖Canvas、SVG或复杂CSS渲染的界面,纯DOM分析会失效。这时,可以启用其视觉能力,结合多模态模型(如Qwen-VL)来分析屏幕截图。
在配置中启用视觉模式,并指定一个支持视觉的模型(如果你的Qwen3.5-9B是纯文本版,则需要换用Qwen-VL等模型):
model:
provider: "openai"
api_base: "http://localhost:11434/v1"
model: "qwen2.5-vl-7b" # 使用视觉语言模型
agent:
executor: "playwright"
use_vision: true # 启用视觉模式,会发送截图给模型
vision_detail: "high" # 截图细节程度
启用视觉后,模型不仅能“读”HTML,还能真正“看”到页面截图,对于识别图标、验证码(当然不是为了破解)、复杂图表等场景有奇效。但代价是Prompt更长,推理速度更慢,需要权衡。
6. 常见问题排查与实战避坑指南
在实际操作中,你一定会遇到各种各样的问题。这里我整理了一份“踩坑实录”,希望能帮你快速排雷。
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| 启动时报错,找不到Playwright浏览器 | Playwright浏览器未安装或路径不对。 | 1. 运行 playwright install chromium 。 2. 检查环境变量 PLAYWRIGHT_BROWSERS_PATH 是否被错误设置。 |
claw.run() 长时间无响应或报超时错误 |
1. 模型服务(Ollama)未启动或端口不对。 2. 模型推理速度太慢。 3. 网络问题导致API调用失败。 |
1. 检查Ollama服务状态: curl http://localhost:11434/api/tags 。 2. 尝试在Ollama交互界面直接提问,看响应速度。优化模型配置(见3.3节)。 3. 检查防火墙和代理设置。 |
| AI点击了错误的元素 | 1. 页面有多个相似元素。 2. 指令描述模糊。 3. 模型“理解”有偏差。 |
1. 在指令中增加更独特的上下文,如“点击 主导航栏中 的登录按钮”。 2. 启用 use_vision ,让模型结合截图判断。 3. 在技能(Skill)中固化经过验证的可靠操作序列。 |
| 页面跳转后AI卡住,不执行下一步 | AI在等待某个页面状态,但该状态一直未出现。 | 1. 在任务描述中明确指定跳转后的 预期结果文本 ,如“等待直到页面标题变为‘订单确认’”。 2. 检查页面是否真的有弹窗、验证码等阻塞流程。可先手动操作一遍,确保流程通畅。 3. 适当增加Playwright的 timeout 配置。 |
| OpenClaw无法处理iframe或新标签页 | 框架默认可能只在主页面上下文操作。 | 需要手动在技能或测试脚本中,使用Playwright的API切换上下文: for frame in page.frames: print(frame.url) 找到目标frame。 frame.click(...) 在frame内操作。 |
执行结果 result 为空或格式错误 |
模型返回的内容无法被OpenClaw解析为有效动作。 | 1. 查看OpenClaw的详细日志(设置 logging.level: “DEBUG” ),看模型原始输出是什么。 2. 可能是 temperature 太高导致输出随机。将其调低至0.1。 3. 检查模型是否支持严格的指令跟随。Qwen3.5-9B-Instruct版本通常表现更好。 |
| 内存/显存溢出(OOM) | 1. 模型太大,显存不足。 2. 浏览器实例过多未关闭。 |
1. 使用量化模型(如4bit)。 2. 确保在 finally 块或使用 async with Claw() as claw: 上下文管理器来正确关闭Claw和浏览器。 3. 限制并发测试任务数。 |
最重要的心得:保持耐心,分步调试。 不要一开始就期望AI能完美执行一个长达20步的复杂流程。从一个简单的“打开网页,点击某个链接”开始,观察日志,理解AI的“思考过程”。逐步增加步骤的复杂性,并在每个关键节点加入你自己的断言或状态检查,确保流程在可控范围内推进。AI驱动的测试不是一劳永逸的银弹,而是一个需要你不断“训练”和“引导”的智能助手。你和它的配合越默契,它的测试效率就越高。
更多推荐
所有评论(0)