编写与设计 YAML 用例
一个典型的 YAML 文件
一份 YAML 文件可以包含多个测试用例,以及用例执行前后的准备和清理步骤。
下面以商城搜索为例:每次运行用例前先打开首页,再搜索商品并验证结果(实际使用时请将网址和商品名称替换为你的业务内容):
在 Midscene Test 中,我们遵循以下术语定义:
- Workflow Document(工作流文档):整份 YAML 文件。
- Case(用例):
cases列表下的单条测试用例。 - Step(步骤):
steps列表下(或生命周期钩子内)的单次 Node 调用,每个步骤只调用一个 Node。 - Hook(生命周期钩子):在用例执行前后运行的准备与清理步骤(如
beforeAll、beforeEach、afterEach、afterAll)。
上面的示例使用了字符串简写形式:gotoUrl 后的字符串会作为 url 参数传入,aiAct 和 aiAssert 后的字符串会作为 prompt 参数传入。如果需要传入更多参数,可以使用下文介绍的对象写法。某个 Node 是否支持字符串简写,以项目的 Node Spec 为准。
用例设计约定
Midscene Test 采用顺序执行与显式状态共享的设计,使每个 Node 的输入参数、执行上下文和依赖关系保持清晰:
- 按声明顺序线性执行:YAML 仅描述线性的测试步骤,不引入 DAG、条件分支或循环语法。如果遇到需要复杂动态编排的场景,建议在外部通过代码生成确定的线性 YAML 步骤序列,再交由 Midscene Test 执行。
- 每一个语句(步骤)都是无状态且独立的:每一个步骤都是一次完全独立的 Node 语句调用,步骤之间不存在隐式的状态和数据传递(不支持跨步骤输出引用语法)。每次调用仅依赖当前步骤显式声明的输入参数以及项目级别的
context。如果你需要在步骤之间显式共享数据,请通过自定义 Node 读写执行项目共享的context。
基于这一约定,每个 AI 步骤的自然语言指令也应当独立完整。例如,下面的断言使用“上一步的图标”来指代检查目标,依赖前一步的指令文本,属于错误写法:
正确的做法是在断言中直接写明检查对象与预期状态,使该步骤本身就能表达完整的检查条件:
简言之,虽然界面本身会保留前一步操作后的画面,但每条自然语言指令都应明确写出目标元素,避免使用“上一步”“刚才那个”等指代词。
使用 Node
Midscene Test 将每一种可在 YAML 中调用的能力称为 Node(节点)。
Node 既可以在用例的 steps 中调用,也可以在 beforeEach、afterEach 等生命周期钩子中调用,语法完全一致。
Midscene Test 注入了 Midscene GUI Agent 上的能力:aiAct 根据自然语言操作界面,aiAssert 验证预期结果,aiWaitFor 等待界面出现指定状态;同时提供了框架内置的 wait 等待指定时长。
在 GUI Agent 的能力 之外,Midscene 还为各个平台预置了专用操作。例如:
- Web:
gotoUrl打开网页、setCookies设置 Cookie、setViewportSize调整浏览器视口大小。 - Android:
launch启动应用、back返回上一页、home返回主屏幕、runAdbShell执行 ADB 命令。
使用脚手架创建项目时,模板会根据所选平台显式注册对应的官方 Node。如果从零手写 midscene.config.ts,框架不会默认注册任何 Node,需要手动引入并配置。各平台支持的官方预置 Node 列表与参数说明,请参阅各平台预置 Node。此外,你也可以按需扩展自定义能力(例如调用业务接口准备测试订单),详见注册自定义业务 Node。
常用 Node
日常编写用例时,主要使用 aiAct 描述操作,使用 aiAssert 验证结果:
界面操作执行完成并不代表测试通过,应在关键节点使用 aiAssert 明确验证预期结果。如果需要自定义 断言失败时的报错提示,可以将参数展开为对象形式:
若需要为后续 AI 操作补充业务背景知识或通用规则(如测试账号约定或弹窗处理),也可以调用 setAIContext 设置或清除上下文。
其他 Node 的调用模式
平台内置操作与自定义业务 Node 采用相同的调用结构:在 Node 名称下方以键值对形式填写参数。下面展示含多个参数与无参数两种常见写法:
其中 setViewportSize 接收一个参数对象,而 clearCookies 不需要参数,传入空对象 {} 即可。这两个 Node 均由 Web 平台预设提供;移动端、桌面端及团队自定义 Node 的可用列表与参数结构,请查阅当前项目的 Node Spec。
例如,当团队在项目中实现并注册了用于创建测试订单的自定义 Node order.create 后,即可在 YAML 中这样调用:
参数值同样支持嵌套对象或数组。例如向 aiAct 传入参考图片时,文本和图片列表共同构成 prompt 对象,而 options 作为同级字段单独配置:
生成当前项目的 Node Spec
不同平台、执行项目(Project)和依赖版本实际注册的 Node 可能有所不同。编写用例时,请勿仅凭其他项目的示例推测当前项目的可用能力。
运行 midscene-test nodes 可以根据项目最终生效的注册结果生成 Node Spec(节点规格说明)——它列出可用 Node、输入参数结构(由 Zod 转换为 JSON Schema)、字符串简写规则及匹配的用例文件路径,是人和 AI Agent 编写 YAML 用例的依据。
查看生成的 Node Spec 示例片段
脚手架在安装依赖后会自动生成 Node Spec。当你修改了 agentClass、顶层 nodes、projects[].nodes、Node 的参数 Schema,或升级了 Midscene 相关依赖包后,都应重新运行以下命令更新 Spec:
你也可以直接调用 CLI 命令,并按需指定测试目录、配置文件或执行项目:
生成命令仅加载项目配置与 Node 定义,不会执行 setup、测试用例或 getAgent,因此无需启动浏览器、连接设备或调用大模型。Node Spec 属于自动生成的文件,请勿手动编辑;配置变更后重新运行生成命令即可。
控制参数与高级配置
设置超时和错误处理
步骤中的 $ 字段用于配置框 架级的步骤控制参数(如超时时间与容错策略)。这些参数由 Midscene Test 处理,不会传递给 Node 的 input。
$ 支持以下两个字段:
timeout:当前步骤的超时时间,单位为毫秒。continue-on-error:设为true时,若当前步骤执行失败,允许继续执行当前阶段的后续步骤(默认值为false)。但如果底层操作未能正常退出或资源清理出现异常,执行仍会中止。
注意,continue-on-error 仅控制当前阶段是否继续往下走;只要用例中有任何一个步骤失败,该用例的最终状态仍为 failed。
步骤超时并不意味着底层的异步操作已立即终止。在进入当前阶段的下一个步骤前,框架会等待已超时的操作彻底退出 (默认最多等待 30 秒,独立计时,不占用下一步的超时时间);若等待超时后仍未退出,则会停止执行后续步骤。底层操作退出后虽然可以继续使用 Agent,但页面或业务状态可能已处于中间态,仍需在后续步骤中确认或重置,详见超时与取消机制。
使用项目变量与环境变量
Midscene Test 会在步骤执行前递归解析 Node 输入参数中的变量占位符:
变量解析遵循以下规则:
${name}:读取当前执行项目的variables配置。若整个字段值仅由${name}构成(未与其他文本拼接),则会保留变量的原始 JSON 类型(如数字、布尔值、对象或数组);对象或数组变量只能作为完整字段值使用,不支持嵌入到字符串中拼接。${{ENV_NAME}}:读取环境变量,解析结果始终为字符串。- 引用未定义的变量会在用例收集阶段直接报错。变量替换仅作用于 Node 的输入参数,不作用于
$控制字段。
关于用例中步骤执行的无状态设计,请参阅用例设计约定。
使用 tags 筛选 Case
你可以为用例添加 tags 标签,以便按场景或平台筛选运行:
工程维护者可以在各个执行项目(Project)中配置 tags.include 与 tags.exclude:排除规则(exclude)始终优先;当包含规则(include)非空时,用例只需命中其中任意一个标签即会被选中执行。
下一步
- 生命周期与并发:了解
beforeAll、beforeEach等钩子的完整执行机制、重试规则与并发策略。 - 开发自定义 Node:封装可复用的业务操作。
- 运行测试:执行用例、获取诊断输出与报告链接。

