如果你还在用XPath和CSS Selector维护UI自动化用例,我强烈建议你留出十分钟,认真了解一下midscene——一个基于大模型智能体的开源测试框架,它正在改变我和很多同行做自动化测试的方式。midscene的核心思路特别简单:你不再需要写一长串元素定位表达式,而是用一句自然语言告诉AI你想做什么,智能体通过视觉理解、语义分析、DOM结构三重信息,自动完成元素定位和操作执行。
这篇文章的目标很明确:从零开始,把midscene的环境搭起来,再通过一个真实的搜索测试demo,让你看到AI自动化测试到底怎么跑通。我还会把这段时间在真实项目里踩过的坑、验证过有效的技巧,全部摊开来讲。无论你是被自动化脚本维护成本折磨的测试开发,还是想看看AI Agent能替测试团队干多少活的负责人,这篇文章应该都能给你一些实际参考。
1. midscene是什么:从"写选择器"到"说人话"的自动化测试
1.1 传统UI自动化的三重痛苦
先聊聊为什么整个测试行业都在关注AI。我做了很多年UI自动化,传统框架(Selenium、Playwright、Appium)用下来,有三个绕不开的痛点。
第一个痛点是元素定位。你写一个用例,可能一半时间花在找选择器上。CSS要写.btn-primary > span.icon-arrow,XPath更要命,还有那些动态生成的class,每次发版都可能变。第二个痛点是页面改版。前端一调整DOM结构,测试脚本就跟着报废,一套几千条用例的回归体系,维护成本高得吓人。第三个痛点是动态内容。登录态、异步渲染、弹窗广告,都让脚本变得脆弱,今天能跑通明天就莫名失败。
这三个痛点本质上指向同一个问题:传统框架让测试人员"翻译"页面结构,而页面结构恰恰是最不稳定的部分。所以当AI智能体出现后,测试圈里很快形成了一个共识——UI自动化的下一个突破口,可能就是"让电脑听懂人话"。2026年被不少同行看作是智能体从概念演示走向工程化落地的分水岭,AI测试工具正是这个趋势里落地最快的场景之一。
1.2 midscene的解题思路:给智能体一双"眼睛"
midscene的解法,一句话总结就是:用多模态大模型充当测试的"眼睛"和"脑子"。
它的工作过程大致是这样:智能体拿到你的自然语言指令后,会同时做三件事——读取当前页面的DOM树结构、截取页面视觉快照、结合语义理解来判断目标元素在哪里。"在搜索框里搜一下关键词"这句话,对人类来说毫无歧义,但传统框架必须知道那个输入框的id到底是search还是kw。midscene不依赖这些,它理解"搜索框"这个概念本身,再从页面结构里找到最匹配的那个元素。
这个设计带来的好处是实打实的。第一,页面class和id随便改,只要UI上的功能和布局没变,用例就不需要动。第二,对于Canvas、WebGL这类难以用DOM定位的复杂页面,视觉理解通道能兜住。我试过在一个纯Canvas绘制的图表页面上跑midscene,传统框架全部抓瞎,它反而能通过视觉找到图表的图例区域。
1.3 midscene的四个核心动作
用过midscene的人应该能感受到,它把自动化能力收敛成四个核心动作,非常清晰:
- run(任务执行):用一句话描述目标,比如"在搜索框输入关键词并点击搜索",智能体负责拆解成一步步操作。
- assert(断言验证):验证页面状态是否符合预期,比如"断言页面上出现包含midscene的搜索结果"。它不靠精确文本匹配,而是语义级判断。
- extract(数据抽取):从页面里抽取结构化数据,比如"提取这张表格里所有产品的名称和价格,按JSON格式返回"。这对回归测试里的数据校验特别有用。
- score(质量评分):对页面视觉质量打分,比如布局是否合理、是否有遮挡等。这块主要面向前端质量评估,在测试里做辅助判断也用得上。
这四个动作覆盖了UI自动化用例里绝大部分场景。更重要的是,它们都是自然语言驱动的,不用写一行选择器。你在用例文件里写测试步骤,就像在写一份给测试员看的手工用例,AI照着执行并验证结果。
2. 半小时环境搭建:从Chrome插件到Playwright工程化
2.1 零代码体验路线:Chrome插件
很多人第一次接触midscene,都是从Chrome插件开始的。midscene官方提供了浏览器插件,安装之后打开任意页面,按快捷键唤起AI面板,直接输入一句话,比如"点击页面上登录按钮,然后输入用户名admin",插件就会自动操作给你看。
这条路线适合两种人:一种是只想验证midscene效果、还没下定决心引入到正规测试流程的人;另一种是测试团队的leader,想五分钟之内让组员看到"AI测试"到底长什么样。插件的执行过程是可视化的,每一步操作都会留下记录,你能看到AI怎么决策、点了哪里、结果如何。
插件体验版一般走的是midscene官方提供的内置模型额度,主要目的就是让你快速上手,不建议依赖它跑大批量测试任务。真要纳入测试体系,得走SDK路线。
2.2 工程化路线:Node.js + Playwright + midscene SDK
正规玩法是走工程化路线:用Node.js(或TypeScript)编写测试脚本,通过midscene SDK和Playwright控制浏览器,再结合测试运行器和CI/CD,把AI测试用例沉淀成正式回归资产。
为什么是Node.js而不是Python或Java?主要因为midscene原生深度绑定Playwright,而Playwright是Node生态出生的。Python当然也有Playwright,但midscene的SDK和社区示例基本都以JS/TS为主。跟着主生态走,遇到问题你能搜到更多现成答案,这个在踩坑阶段特别重要。
我的建议是Node版本用20+。装之前先确认本机Node和npm可用,然后初始化一个npm项目:
mkdir midscene-demo && cd midscene-demo npm init -y npm i -D @midscene/web playwright npx playwright install chromium第4行是下载Chromium浏览器内核,网络下载速度不理想时这里容易卡住,后面的"常见问题"里我会讲怎么处理。
2.3 模型配置:内置体验与外部API
midscene本身不生产模型,它依赖一个多模态大模型来做理解和决策。模型选型直接决定测试效果和成本。
第一次体验时,你可以用内置模型额度,不配任何API Key就能跑,缺点是有调用次数限制,并发能力弱,不适合正式环境。正式接入时,通常走OpenAI兼容接口,可选范围很大:GPT-4o和Claude的视觉理解能力强、准确率高,但API成本偏高;通义千问的Qwen-VL-Max在国内团队里用得挺多,中文理解好、价格适中;DeepSeek最近在多模态上进步很快,成本控制得很激进,也值得关注。
配置上建议通过环境变量注入,避免把Key写进代码仓库。我习惯在项目根目录放一个.env.example,里头列出MIDSCENE_MODEL、MIDSCENE_API_KEY、MIDSCENE_BASE_URL三个变量,真正的内容写进本地.env,由启动脚本加载。
2.4 初始化项目并跑通第一个脚本
依赖装好、模型配好之后,写第一个脚本验证整体链路。脚本逻辑非常简单:打开必应首页,自然语言驱动搜索,然后退出。
// demo-bing.mjs // 基于midscene 0.9.x + playwright import { chromium } from 'playwright'; import { createAgent } from '@midscene/web'; const browser = await chromium.launch({ headless: false }); const page = await browser.newPage(); const agent = createAgent({ model: process.env.MIDSCENE_MODEL || 'gpt-4o', apiKey: process.env.MIDSCENE_API_KEY, llmOptions: { baseUrl: process.env.MIDSCENE_BASE_URL }, }); await page.goto('https://www.bing.com'); await agent.run('在搜索输入框输入 "midscene AI" 并敲击回车'); await agent.assert('页面上出现了 "midscene" 相关的搜索结果'); await browser.close();这里我用的是page.goto直接进入页面,再用agent.run做操作。跑通的标志是:浏览器自动打开必应、输入关键词、回车,然后日志里显示断言通过。第一次跑建议开有头模式(headless: false),亲眼看到AI在操作,心里才有底。
3. Demo演示:一个搜索测试用例的完整落地
3.1 场景需求与用例设计
为了避免"能跑但说不清楚干了啥",我设计一个稍微完整的demo。
场景:测试"在必应中搜索 midscene,验证搜索结果能正常展示"。这个场景覆盖了UI自动化的标准路径——页面打开、输入操作、异步结果加载、结果断言。
我把用例拆成四个步骤:
- 打开必应首页
- 在搜索框输入关键词"midscene AI 自动化测试"并回车
- 等待搜索结果加载完成
- 断言页面出现与关键词相关的搜索结果
这几个步骤里,最关键的是第4步。传统做法是写expect(page.locator('#b_results')).toContainText('midscene'),一旦id变化就会失败。midscene用语义断言,AI判断"页面上有没有指向midscene的搜索结果",页面结构变了也不影响结论。
3.2 完整代码实现(带注释)
代码直接用上一章的框架,加上显式等待和错误信息输出。我用必应做演示,是因为它页面结构稳定、不需要登录,也不容易触发反爬机制,适合当AI测试的练手页面。
// midscene-search-demo.mjs // 环境:Node 20 / midscene 0.9.x / playwright import { chromium } from 'playwright'; import { createAgent } from '@midscene/web'; const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms)); (async () => { const browser = await chromium.launch({ headless: false }); const page = await browser.newPage(); page.setDefaultTimeout(30000); const agent = createAgent({ model: process.env.MIDSCENE_MODEL || 'gpt-4o', apiKey: process.env.MIDSCENE_API_KEY, }); console.log('[1/4] 打开必应'); await page.goto('https://www.bing.com', { waitUntil: 'domcontentloaded' }); console.log('[2/4] 执行搜索'); await agent.run('在搜索输入框中输入 "midscene AI 自动化测试" 并按下回车'); console.log('[3/4] 等待结果加载'); await delay(2000); console.log('[4/4] 断言结果'); await agent.assert('搜索页上出现了与 midscene 相关的结果标题'); console.log('PASS: 断言通过'); await browser.close(); })();这里有个细节值得说:为什么在AI操作之后加一个delay?因为搜索结果加载是异步的,AI的视觉判断在页面还没渲染完成时可能会误判——它看到页面还停留在加载状态,就以为搜索没生效。加一个适度的等待,准确率会高很多。
3.3 运行与结果解读
运行命令很简单:
export MIDSCENE_MODEL=gpt-4o export MIDSCENE_API_KEY=你的Key node midscene-search-demo.mjs你要关注两个输出。第一个是agent.run执行过程里AI的操作轨迹,它会展示AI"看到"了什么、点击了哪里,每条操作都会有时间戳。第二个是agent.assert的断言结果,通过就是PASS,不通过则会返回AI认为的页面状态文本。
如果断言没通过,先看是不是页面真的没加载出来,再看是不是AI理解有偏差。比如AI可能认为"midscene相关的结果标题"必须包含完全一致的英文单词,而实际页面展示的是中文描述。这时候把断言描述改得更明确、更贴近业务语言,就能解决。这个demo虽然简单,但它完整走通了AI自动化测试的最小闭环,往里填充更多业务逻辑,就能变成一个正式的UI测试用例。
4. 进阶玩法:从demo到可交付的测试工程
4.1 用YAML编排复杂测试场景
一个真实的测试项目不可能只有一个操作。midscene支持把测试脚本用结构化形式管理起来。
比如一段回归用例可以这样组织:打开首页、登录、点击创建、验证创建结果、退出。你可以把每个步骤写成自然语言配置项,放在YAML文件里统一管理:
name: 用户创建流程回归 steps: - action: 打开 https://your-app.com - action: 在用户名输入框填入 test_user,密码填入 test_pass,点击登录 - action: 点击左侧菜单的"创建项目" - action: 在项目名称输入框填入 "自动化测试项目",点击保存 - assert: 页面出现 "创建成功" 的提示,并且列表里出现了 "自动化测试项目"测试运行时逐条执行,任何一个步骤断言失败,就停下来并输出对应的页面快照和操作日志。这样做的好处很直接:测试用例的维护从"改代码"变成"改描述"。业务同学可以把需求变更直接翻译成用例描述,测试团队不用再面对一堆晦涩的XPath和class名。
4.2 接入CI/CD流水线:让AI测试自动跑起来
AI测试要真正落地,必须进CI/CD。项目结构建议是:测试脚本放在独立目录,每次提交代码后自动安装依赖、启动测试服务、跑AI测试、生成报告。
GitHub Actions的配置大概长这样:
name: UI Test on: [push] jobs: ai-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - run: npm ci - run: npx playwright install chromium - run: npm test env: MIDSCENE_MODEL: ${{ secrets.MIDSCENE_MODEL }} MIDSCENE_API_KEY: ${{ secrets.MIDSCENE_API_KEY }}关键点有两个。第一,模型API Key用secrets方式注入,不要在配置里明文出现,这个习惯能避免很多安全事故。第二,建议在测试命令外面套一层失败重试,因为AI判断带有一定概率性,单次失败不代表功能有bug,重跑一次往往是PASS。我见过不少团队因为第一次跑红就直接判负,结果误报率高得吓人,最后AI测试方案被整个否掉,其实只是策略没设计好。
4.3 用数据抽取做结构化验证
除了常规的UI操作和断言,extract功能在测试里的价值经常被低估。
比如你要验证一个表格页的分页功能是否正常,传统做法是逐项比对页面文本,写一堆解析逻辑。用midscene,你可以一句话让AI把当前页的表格内容全部抽出来,以JSON格式返回,然后在代码里做结构比对。数据量一大,这种方式的效率优势非常明显。
我实际用下来,extract对页面结构变化的容忍度很高。表格某个列的样式变了、字段顺序调整了,只要语义没变,抽取结果就是稳定的。这比原来写一堆选择器加解析逻辑省心太多。而且AI抽取出来的数据是天然结构化的,可以直接喂给后续的断言逻辑或数据比对工具,链路上省掉不少手工转换。
5. 实战避坑:环境搭建与稳定性问题实录
5.1 装环境就翻车的三个坑
第一个坑是Playwright浏览器下载慢甚至失败。这几乎是每个新手都会遇到的问题。我的处理办法是设置下载镜像环境变量,让浏览器内核走镜像源下载,或者在CI里提前把浏览器缓存打进镜像。核心思路就是别直接连官方源,具体镜像地址和配置方式网上有大量现成方案,这里不展开。
第二个坑是Node版本过旧导致SDK安装失败。如果你还在用Node 14甚至更老的版本,@midscene/web安装时大概率会报错。建议直接上Node 20 LTS,很多莫名其妙的报错就消失了。
第三个坑是Headless模式(无头模式)下断言失败率高。AI的视觉理解依赖页面渲染截图,无头模式下截图渲染容易不完整,导致AI漏判元素。调试阶段一定先跑有头模式,等脚本稳定之后再切无头。我见过有人在无头模式下反复调整提示词,调了一天都没找到原因,切回有头模式一眼就看出是渲染问题。
5.2 模型选型的成本与效果平衡
模型选得不对,midscene的体验会两极分化。便宜的模型经常识别不准确,页面元素没找到就随便点;贵的模型效果好,但跑几百条用例的成本也不低。
我的经验是分场景选模型:日常调试用便宜的轻量模型,正式回归阶段切到准确率更高的旗舰模型。还可以给每条用例设置合理的超时和重试次数,防止单次模型调用卡死整个测试流程。
另外一个成本技巧是合并操作。比如"登录"这个过程,完全可以拆成"输入用户名"、"输入密码"、"点击登录"三个独立操作,但这样就是三次模型调用。更好的做法是写成一句"在登录页填入用户名和密码并登录",让AI一次性完成,既省API调用次数,也减少中间环节的失败概率。
5.3 稳定性优化与兜底策略
AI测试最大的争议是"不稳定性"。我自己实测的体感是:单个AI操作的成功率大概在90%上下,但在关键步骤上叠加一层稳定性策略之后,用例整体成功率能到95%以上。
具体做法有几个:步骤执行前先等待页面完全加载;操作失败后自动重试;对于关键断言,把语义断言和文本断言做双重校验;针对弹窗、登录态等特殊情况,在脚本里预设处理路径。
还有一个很实用的经验:不要让AI一口气执行10个步骤的长链路,把它拆成2-3个短动作组合,成功率会明显上升。AI的容错能力再强,也架不住链路过长导致的误差累积。打个比方,让AI"一步步从A走到J"成功率高,还是"从A走到J中间还要处理两个弹窗"成功率高?答案显而易见。
我自己在真实项目里跑midscene跑了大概一个季度,最深的体感是:它不会完全取代传统自动化测试,但它把"测试脚本维护成本"这个老大难问题压下去了一大截。以前最怕的页面改版,现在基本只需要在用例描述层做微调,不用再一行行改选择器。
最后给想尝试的读者一个建议:别一上来就追求把核心回归全部迁到AI测试,先挑一条经常因为页面改版而挂掉的用例,用midscene把它重写,跑两周对比一下维护成本,你会有很明确的判断。工具轮子还在快速迭代,但"用自然语言描述测试意图"这个方向,我是比较笃定的。