编写和运行测试用例
框架维护者完成 Test Project 配置后,人类或 Agent 可以使用项目注册的 Node 编写测试用例。开始编写前,建议运行 describe-nodes 生成 Node 说明书,确认项目提供的能力和输入参数。
如果你尚不了解整体设计,请先阅读 Test Runner 概览。如果项目尚未配置,请阅读扩展和维护 Test Runner。
核心概念
@midscene/test 使用以下概念描述测试项目。
- Test Project(测试项目):由
midscene.config.ts定义的顶层配置,负责注册共享 Node,并配置默认运行目标或projects数组。 - Execution Project(执行项目):Test Project 内的一项子配置,描述一个运行目标及其平台、Project setup、文件和标签筛选、变量与 retry 策略;它不是独立于 Test Project 的同级实体。
- Workflow Document(工作流文档):被 Execution Project 选中的 YAML 文件,包含生命周期和多个 Case。
- Lifecycle Step(生命周期步骤):在 Workflow Document 的
beforeAll、beforeEach、afterEach或afterAll钩子中声明并执行的步骤,用于进行数据准备、状态重置、资源清理等辅助性操作。 - Case(用例):由多个 Step 组成的具名测试用例。
- Step(步骤):在 YAML 中对 Node 的一次调用。
- Node(节点):平台开发者注册的执行能力,例如
aiAssert或order.create。
Node 定义团队可用的执行能力,YAML 定义每个测试用例如何组合这些能力。
编写 YAML 测试用例
每个 Workflow Document 必须包含非空的 cases 数组。每个 Case 必须包含 name 和非空的 steps。
运行器按照 YAML 中的声明顺序执行 Case。一个 Case 失败后,运行器会记录失败结果,并继续执行后续 Case。
编写 Step
每个 Step 只能调用一个 Node。如果调用时只需传入 prompt 参数,可以使用字符串简写。
上面的写法等价于:
业务 Node 可以接收自定义参数。
设置超时和错误处理
$ 用于设置由运行器控制的 Step 参数。运行器不会将这些参数传入 Node 的 input。
支持以下两个字段:
timeout:Step 的超时时间,单位为毫秒。continue-on-error:设为true后,即使 Step 失败,运行器也会继续执行当前阶段的后续 Step。默认值为false。
continue-on-error 只控制运行器是否继续执行。只要有 Step 失败,Case 的最终状态就是 failed。
使用 Project 变量与环境变量
运行器会在执行前递归解析 Node input:
${name}读取当前 Execution Project 的variables;独占整个标量时保留原始 JSON 类型。${{ENV_NAME}}读取环境变量,结果始终是字符串。- 对象或数组变量可以作为完整值使用,但不能嵌入更长的字符串。
- 未定义变量会在收集阶段失败。变量只解析 Node input,不解析
$。
Workflow YAML 不提供 set、saveAs 或 Step 输出表达式。自然语言 Node 可以通过运行器维护的只读执行历史理解前序结果。
使用 tags 筛选 Case
框架维护者在每个 Execution Project 中配置 tags.include 与 tags.exclude。exclude 始终优先;include 非空时,Case 命中任意一个 include tag 即会被选中。
定义执行生命周期
Workflow Document 可以在 cases 前后声明生命周期 Step。
一个 Execution Project 的完整执行顺序如下。
各阶段的职责如下:
beforeAll和afterAll对每个 YAML 文件各运行一次,负责文档级业务准备与清理。beforeEach和afterEach对每次 Case attempt 各运行一次。- retry 会以新的 run ID、Agent scope、缓存 scope 和 Case history 重跑整个 Case,但不会重跑
beforeAll。 - Node 可以注册 attempt 或 Document scope 的内部清理,例如释放 Agent 和生成报告;这些清理在相应 scope 结束时执行。
即使 Case 主体失败,afterEach 仍会执行。
如果 beforeAll 失败,运行器会将当前文件中的 Case 标记为 not-run,但仍会执行 afterAll 和已经注册的 Node 清理。
Project setup 在该 Project 的 Workflow Document 之前只执行一次,Project teardown 始终按 LIFO 顺序执行。收到中断信号时,当前 Step 会被取消,但 cleanup hook 与已注册 teardown 会使用可执行清理工作的 signal。
运行测试
在项目根目录下,使用以下命令运行 YAML 测试用例:
指定用例目录或文件
默认情况下,运行器会递归查找并执行项目根目录下的所有 .yaml 和 .yml 文件(自动忽略 node_modules 和 .git)。
如果你只想执行特定目录或特定用例文件,可以将其作为参数传入:
过滤运行目标与配置文件
如果项目配置了多个运行平台或环境,你可以指定仅运行特定的 Execution Project,或者通过命令行指定自定义配置文件:
当发生用例运行失败、文档解析失败或收集阶段发生错误时,CLI 会返回退出码 1。
查看测试结果
每次测试运行结束后,你可以在控制台直接看到用例的执行状态和简要汇总。同时,运行器会在本地生成可视化的测试报告。
Midscene 可视化报告
运行器会自动将详细的测试步骤、界面截图和 AI 决策过程记录到交互式 HTML 报告中。
默认情况下,报告保存在:
你只需在浏览器中打开该目录下的 HTML 文件,即可直观地看到每一个 aiAct 和 aiAssert 的执行轨迹、元素定位结果以及完整的历史截图。
提示:如果想修改可视化报告的默认保存目录,可以通过修改
midscene.config.ts中的output.reportDir配置来实现。
当前限制
目前版本的 测试运行器存在以下局限性,在编写用例时需予以注意:
- 无并行执行:在单个 Execution Project 内部,所有的 Workflow Document、Case、attempt 和 Step 均为串行执行,暂不支持用例维度的并发。
- 无控制流:不支持 DAG(有向无环图)、分支(If-Else)或循环(Loop)等控制流,用例按照声明顺序线性执行。
- 无用例间数据依赖:不同的 Workflow Document 之间是完全隔离的,无法传递或共享执行中的数据。
- 仅限本地加载:暂不支持直接从远程 URL、npm 包或 Git 仓库加载并执行 YAML 文件。
此外,运行器会在执行前对所有 YAML 文件进行静态收集和校验。若存在未知的顶层字段、未注册的 Node 或无效的 Step,运行器会立即抛出收集错误(Collection Error)并中断运行,不会等到执行该 Case 时才报错。

