用 AI 为前端测试提效?试试这套 SDD 驱动的 UI 自动化测试方案
前端应用开发完成后,总希望借助 AI 来辅助测试,特别是边界条件与异常处理场景往往令人头疼。如今代码中由 AI 生成的比例越来越高,如果继续人工编写测试用例,成本会显著上升。很自然地,我们开始思考:能否让 AI 自动生成测试用例并执行测试流程?
经过一段时间的调研,最终决定采用 SDD 规范来约束项目的前端 UI 自动化测试方案。
SDD 的核心思路非常直观:将设计规范从静态文档转化为程序能够理解的断言。具体而言,就是把存放在 src/style/ 下的 Ant Design Vue 样式规范提取为可执行的测试契约。接着通过组件级测试、基于 OpenAPI/Spec 驱动的端到端场景以及 CI 门禁,构建出完整的测试闭环。测试不再仅仅是验证“页面能否点击”,而是验证“页面是否严格按照规范呈现、业务路径是否正常运行,并在持续迭代中保持一致性”。
方案详解
核心目标
| 能力 | 选型 | 作用 |
|---|---|---|
| UI 自动化执行 | @midscene/web |
通过 Chrome Bridge 操控浏览器,完成 AI 操作与断言 |
| 精确样式断言 | page.evaluate + getComputedStyle |
校验颜色、字号、边框、圆角、间距等 CSS 计算值 |
| 场景生成 | OpenAPI Spec + OpenSpec AC | 基于接口和验收条件自动生成结构化 E2E 场景 |
| 脚本运行 | tsx |
直接运行 TypeScript 格式的测试文件 |
| 报告沉淀 | 自定义 Logger / Reporter | 输出控制台日志、截图以及 HTML 格式报告 |
| CI 门禁 | Puppeteer headless | 无桌面环境下执行精确断言,默认跳过 AI 视觉断言 |
这套方案的关键不在于某个单点工具,而是将“规范、场景、执行、报告、门禁”分解为清晰的工程层次。
方案架构
采用四层架构:规范定义层 → AI 测试生成层 → 测试执行层 → 报告层。流程清晰:规范来源层收集样式规范、OpenAPI Spec 以及验收条件;AI 测试生成层据此生成结构化的测试场景;执行层通过 Midscene Agent 驱动浏览器完成导航、交互与断言;最后报告层汇总所有结果。
规范来源层包含三类输入:
src/style/:项目中 30 多个组件的样式规范,是颜色、边框、圆角、间距等 UI 契约的真实来源。openspec/specs/spec.md:以 AC 编号维护验收条件,便于检查覆盖率和同步文档。tests/fixtures/openapi.json:由 Apifox MCP 预获取的 OpenAPI Spec 缓存,用于推导接口对应的业务页面与操作路径。
执行层分为两种模式:本地开发时使用 Chrome Bridge 连接真实 Chrome,便于 AI 视觉与交互调试;CI 环境中则使用 Puppeteer headless,专注于可重复、可量化的 CSS 精确断言。
规范先行
SDD 的第一步,是将视觉规范从“文档描述”转化为“程序可判断的断言”。在 tests/specs/index.ts 中维护了统一的 SDDSpec,统一定义了组件选择器、状态以及期望样式值。比如按钮、表格、弹窗、表单、菜单这些核心组件都被抽象为结构化的规范。
这样做能带来几个直接收益:
- 样式规范集中维护,避免每个测试文件散落大量 selector 和 expected value。
- 规范变更时优先修改契约,测试执行后即可暴露影响范围。
- 测试报告能按组件和状态聚合失败项,而不是只给出“页面截图不一致”。
双模式断言
UI 自动化测试常见的陷阱,是把所有视觉判断都交给截图或 AI。我们采用的策略是“精确 CSS 断言占 70%,AI 视觉断言占 30%”。
对于颜色、字号、边框、圆角、间距等可量化属性,通过 window.getComputedStyle() 获取真实计算值,并执行颜色归一化、零值归一化以及视口单位兼容。例如 #2a50d7 会被归一化为 rgb(42,80,215) 再进行比较,避免因浏览器返回格式差异导致误报。
而对于布局感知、元素存在、操作路径这类难以稳定量化的内容,才交给 Midscene 的 AI 断言。这样既保留了 AI 对页面语义和交互的理解能力,又让关键视觉契约具备可重复的门禁价值。
交互状态也被单独处理。针对 hover、focus、active 等状态,测试不会静态读取伪类,而是先通过浏览器事件触发,再采集计算样式,确保“用户真实操作后的样式变化”也能被验证。
组件级验证
组件测试位于 tests/components/,覆盖 Button、Table、Modal、Form、Menu 五类高频基础组件。组件级验证的价值在于尽早将问题拦截在最小单元:如果主按钮 hover 颜色出错,无需跑完完整的用户新增流程才能发现。
| 组件 | 覆盖内容 |
|---|---|
| Button | default / primary / dashed / link / ghost,多种状态样式验证 |
| Table | 表头背景、边框颜色、无圆角、行 hover 背景 |
| Modal | 标题字重、body 内边距、footer 布局 |
| Form | 表单项间距、label 对齐、控件行高 |
| Menu | 选中态、hover 态、子菜单展开、折叠宽度 |
本地全量入口 tests/run-all.ts 会先并发执行这些组件测试,组件测试通过后,再进入 E2E 场景执行。
E2E 案例
传统 E2E 测试的常见痛点在于测试脚本写死,一旦接口或页面变动,维护成本便迅速上升。我们这里将场景来源拆分为两条线。
一条来自 OpenAPI。解析接口路径、方法、参数、响应及实体模型,再将信息映射到页面和业务动作。例如 GET /api/users 对应表格加载,POST /api/users 对应新增用户流程。
另一条来自 OpenSpec AC。维护规范化的验收条件,解析 AC 条目并与场景快照比对,输出覆盖率。同时还支持从 AC 直接生成或合并 E2E 场景。
生成后的场景会缓存到快照目录,支持人工审查和二次调整。执行时逐个加载场景,驱动 Midscene Agent 完成导航、点击、填表、断言,并在关键步骤注入 SDD 样式验证。
测试隔离与认证
这套方案还解决了后台系统测试中两个实际问题。
第一是登录问题。项目存在 SSO 路由守卫,测试不能每次都依赖真实登录页面。因此提供了认证绕过能力:本地模式优先复用已有的 session,必要时注入 localStorage;CI 模式则通过请求拦截与 localStorage 注入完成认证准备。
第二是隔离问题。E2E 场景之间容易残留弹窗、Toast、表单状态或路由状态,因此执行器会在场景前后进行页面状态清理,降低串行执行时的上下文污染。
这些处理让测试不再是“仅在我机器上能跑的脚本”,而是可以融入团队工作流的工程资产。
三种运行形态
项目根据不同阶段的运行诉求,拆分出三类命令。
本地开发阶段,既可以单独验证某个组件,也能运行完整链路。
CI 阶段,脚本默认设置 TEST_MODE=ci 和 SKIP_AI=true,使用 Puppeteer headless 执行精确 CSS 断言,避免 AI 视觉判断带来的不稳定性。
变更验证阶段,tests/run-changed.ts 会基于 git diff 推断受影响的测试,只执行受影响的组件或 E2E 场景。
此外,还提供了规范同步、覆盖分析和样式基线管理等辅助命令。
这几类命令共同构成了从开发调试、提交前自检到 CI 门禁的分层测试策略。
报告与反馈闭环
测试执行结果会通过自定义 Logger 和 Reporter 汇总,输出到 midscene_run/report/。报告关注以下几类信息:哪些组件规范通过或失败;失败项的实际值与期望值;E2E 场景执行步骤及失败上下文;规范覆盖率与场景覆盖关系;必要时记录截图,辅助定位视觉或交互问题。
这种报告结构比单纯的截图对比更适合团队排障。例如当表格头部背景失败时,报告可以直接指出实际颜色值与期望值不一致,而不是让开发者在截图中猜测问题。
项目配置
安装依赖
方案使用了 Midscene AI 作为前端视觉测试插件,采用 Chrome 桥接模式,通过本地项目脚本控制桌面版 Chrome。这种方式能够复用本地浏览器的 cookies、插件和页面状态,与自动化脚本协作完成任务。
- 浏览器安装 Midscene.js 扩展。
- 项目安装依赖:
pnpm install -D @midscene/web dotenv puppeteer - 在项目
.env文件中配置 AI 模型。
目录结构
项目在 tests/ 目录下清晰组织了各类测试资源:
specs/:SDD 规范定义文件。utils/:工具封装,包括 Midscene 助手、报告生成、日志、样式断言和基线管理。components/:五个基础组件的测试文件。e2e-generator/:核心创新部分,包含 OpenAPI 解析器、场景生成器、执行器、Spec 解析器和场景转换器。fixtures/:测试凭据和 OpenAPI Spec 缓存。- 根目录下还有全量、增量、CI 等执行入口。
脚本命令
项目提供了丰富的脚本命令,覆盖了单组件验证、Spec 校验、E2E 生成与执行、样式基线管理、全量执行等场景。这些命令共同形成了从开发调试到 CI 门禁的分层测试策略。
项目测试
使用流程
pnpm dev启动开发服务器。- 打开已安装 Midscene 扩展的 Chrome 浏览器。
- 可以单独验证某个组件。
- 核心流程:先
pnpm test:e2e:generate生成 E2E 场景,再pnpm test:e2e:run执行。 - 全量执行:
pnpm test:all,并发执行组件测试,串行执行 E2E 场景。 - 查看控制台输出和
midscene_run/report/下的 HTML 报告。
关键工程取舍
这里有几个值得复用的取舍经验。
第一,MCP 预获取优于运行时依赖 MCP。tsx 脚本无法直接调用 IDE 进程中的 MCP 工具,因此我们把 Apifox OpenAPI Spec 预获取到 tests/fixtures/openapi.json,这样测试生成器可以离线运行,也便于将接口规范变更纳入版本管理。
第二,测试契约应使用编译后的选择器。Ant Design 前缀由环境变量控制,测试规范中通过 VITE_ANT_PREFIXCLS 适配实际的 CSS 类名前缀,避免源码变量与浏览器 DOM 不一致。
第三,AI 不介入强门禁的核心判断。AI 擅长理解页面语义和操作路径,但颜色、字号、边框这类门禁项更适合做精确断言。将 AI 放在它更擅长的位置,稳定性会显著提升。
第四,场景生成需要可缓存、可审查。完全动态生成 E2E 场景虽然很酷,但团队协作需要可解释和可追溯。快照缓存让 AI 生成的结果可以被人工校正,也让后续执行更加稳定。
落地收益
这套 SDD UI 自动化测试方案带来的收益主要体现在四个方面:
- 规范不再停留在文档中,而是变成可执行、可失败、可阻断的测试契约。
- UI 回归更早暴露,组件级测试能够快速定位基础样式偏差。
- E2E 不再完全依赖手写脚本,可以从 OpenAPI 和 AC 条目推导业务场景。
- 本地、CI、增量测试各有边界,既能保持反馈速度,也能覆盖关键风险。
对于一个持续演进的管理后台来说,这种测试体系的价值不只是“自动化覆盖率更高”,而是把设计规范、接口契约、业务验收和工程门禁接入同一个反馈回路。随着页面和组件增多,规范越早被程序化,后续维护成本就越可控。
结语
当前方案已经覆盖了组件规范、页面场景、OpenAPI 场景生成、OpenSpec 覆盖率、CI 精确断言以及增量测试,显著提升了 UI 测试效率。不过前期在 Spec 的生成与矫正上确实花费了不少时间,后续可以继续对这个流程进行优化。
