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的智能体。

它的工作流程通常是这样的:

  1. 观察 :OpenClaw通过底层驱动(如Playwright)获取当前页面的状态。这个状态可以是截屏图片,也可以是结构化的HTML/DOM信息,或者两者都有。
  2. 思考 :它将当前页面状态、历史操作记录以及你的自然语言指令(例如:“点击登录按钮”)一起,打包成一个精心设计的提示词(Prompt),发送给大模型(如Qwen3.5-9B)。
  3. 决策 :大模型分析提示词后,输出一个结构化的动作指令。这个指令不是简单的“click”,而可能是 {"action": "click", "selector": "button:has-text('登录')", "reason": "根据指令,需要点击登录按钮以进入下一步"}
  4. 执行 :OpenClaw解析这个动作指令,调用对应的底层API(如Playwright的 page.click(selector) )来执行操作。
  5. 循环 :然后回到步骤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在内部做了很多事情:

  1. 任务规划 :模型首先会理解整个任务,并将其分解成一系列顺序执行的子目标。
  2. 元素定位 :对于每个子目标(如“点击登录链接”),模型会结合当前的页面截图或DOM,去“寻找”最匹配的元素。它可能通过文本内容(“登录”)、元素类型( <a> 链接)、位置(右上角)等多种特征综合判断。
  3. 动作生成与执行 :找到元素后,模型生成具体的Playwright操作指令,如 page.click('a:has-text("登录")') ,然后执行。
  4. 状态验证与循环 :执行后,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驱动的测试不是一劳永逸的银弹,而是一个需要你不断“训练”和“引导”的智能助手。你和它的配合越默契,它的测试效率就越高。

更多推荐