开发自定义 Node
自定义 Node 用于将业务操作封装为可在 YAML 用例中直接调用的步骤。本文介绍如何定义与校验输入参数、在多个 Node 之间共享上下文数据,以及处理异步取消与资源清理。
关于平台环境、Agent 接入和运行参数配置,请参阅配置测试工程。
- 注册自定义业务 Node:定 义业务操作、在 YAML 中调用,并通过生成 Node 说明书验证注册结果。
- Node 执行参数:区分业务输入参数(
input)与框架级步骤控制参数($)。 - 跨 Node 共享上下文:在多个步骤之间创建、读取和清理共享测试数据。
- 进阶用法:返回结构化结果、处理错误与取消信号,以及管理资源生命周期。
注册自定义业务 Node
自定义 Node 从 YAML 步骤中接收参数并执行对应的 TypeScript 逻辑。下面以创建测试用户数据为例,演示如何将用户信息写入本地 JSON 文件(实际业务中可替换为调用后端接口或写入数据库)。
1. 定义并注册 Node
在 midscene.config.ts 中使用 defineNode() 定义节点,并将其加入 nodes 数组:
各字段的作用如下:
name:在 YAML 中调用该操作时使用的名称。inputSchema(可选):使用 Zod 定义输入参数结构。定义后,Midscene Test 会在调用execute()前自动校验参数 ——例如示例中的z.string().min(1)要求姓名非空,.email()校验邮箱格式,z.strictObject()拒绝未声明的多余字段。若参数校验不通过,框架会直接抛出NodeInputValidationError。同时,TypeScript 会根据该 Schema 自动推导execute({ input })中input的类型,而.describe()中的说明文字则会输出到自动生成的 Node 说明书中。execute({ input }):接收校验通过的参数并执行具体逻辑。将定义好的 Node 加入配置的nodes数组后,即可在 YAML 用例中调用(扩展已有工程时,将其追加到原有的nodes数组即可)。
2. 在 YAML 中调用
创建 cases/user.yaml 并调用刚刚注册的 user.create:
运行测试时,Midscene Test 会解析 YAML,找到名为 user.create 的 Node,并将 { name: "Alice", email: "alice@example.com" } 作为 input 传给 execute()。
示例中使用 async execute({ input }) 配合 await 等待文件写入完成;如果写入过程中抛出异常,该步骤即会标记为失败。
3. 生成 Node 说明书,验证注册结果
保存配置后,运行以下命令生成 Node 说明书:
该命令会加载项目配置,并在当前目录生成 midscene-node-spec.md(若配置了 projects,则会为每个执行项目生成 midscene-node-spec.<project-name>.md)。打开生成的说明书,确认其中包含以下内容:
- 可用 Node 列表(Available Nodes)中包含
user.create。 - 节点详情中包含“创建测试用户数据文件。”这一功能说明。
- 包含
name、email两个输入字段及其描述信息。
这一步仅用于验证 Node 是否成功注册、输入 Schema 是否可正常导出,不会实际执行 execute()。后续每当修改了 Node 定义或注册配置,都可以重新运行该命令更新说明书,供测试工程师和 AI Agent 查阅。详见生成当前项目的 Node 说明书。
为 Node 声明字符串简写
如果某个 Node 只有一个必填的字符串参数,可以通过 stringInputKey 指定字符串简写映射的目标字段名:
配置 stringInputKey: 'message' 后,在 YAML 中直接传入字符串即可映射到 input.message:
由于字符串简写只能提供一个字段的值,若 inputSchema 中还包含其他没有默认值的必填字段,简写调用仍会因缺少字段而校验失败。省略 stringInputKey 或将其设为 false 时,该 Node 不支持字符串简写,必须使用键值对对象传参。
Node 执行参数
Midscene Test 调用 execute() 时,会传入一个包含业务参数与运行上下文的参数对象,你可以通过 execute({ input, $, context }) 按需解构所需的字段。
业务参数与步骤配置
在参数对象中,input 存放由 Node inputSchema 校验后的业务参数,而 $ 存放由框架控制的步骤级配置(如超时时间、失败后是否继续执行)。
例如,在 YAML 中为 user.create 同时传入业务参数和 $ 配置:
框架会自动将 $ 从业务参数中剥离(因此 inputSchema 中无需声明 $),并将字段名转换为驼峰格式。在 execute({ input, $ }) 中可以分别读取到:
步骤超时与 continue-on-error 行为均由框架统一调度。注意,开启 continue-on-error 虽然允许当前阶段的后续步骤继续执行,但仍受资源安全限制约束,且该步骤本身的失败依然会使整条用例最终标记为 failed。

