创建和使用测试项目
本文从创建项目开始,介绍如何运行示例、了解可用的测试操作、编写 YAML 用例和查看运行结果。已有 Midscene Test 项目的读者可以直接从了解可用的测试操作开始。
整体设计见 Midscene Test 概览。业务操作的实现方式见编写自定义 Node,运行环境和执行参数见配置测试项目。
创建项目
1. 生成项目文件并安装依赖
准备 Node.js ^20.19.0 || ^22.12.0 || >=24.0.0 和 pnpm。需要交互式引导时,运行:
命令会依次提示选择项目目录、平台、包管理器,以及是否安装依赖。也可以直接传入参数,例如使用 pnpm 创建 Web 测试项目:
可用参数如下:
每个平台目前提供一个起步模板,通过 --platform 选择,均使用原生 cases/steps Test 文件。在 CI 等非交互式环境中,必须提供目录和 --platform;未设置 --skip-install 时会安装依赖。
常用示例:
按提示安装依赖。命令会生成平台配置和示例用例,安装依赖后还会生成 Node 说明书。Web 项目的主要文件如下:
其他平台模板在 midscene.config.ts 中定义 todo.setup,不包含 nodes/todo.ts,说明书文件名使用对应平台名称,例如 midscene-node-spec.ios.md。创建项目和生成说明书不会运行测试,因此这一步不需要模型 API Key、浏览器或设备。生成项目中的 README 会说明平台准备和示例运行方式。
如果跳过安装或安装失败,可以进入项目目录执行 pnpm install。需要重新生成 Node 说明书时,执行 pnpm run nodes。
2. 配置模型与运行环境
将 .env.example 复制为 .env,按照模型配置填写模型名称、服务地址和 API Key。
运行测试前,检查模型连接和 Midscene 兼容性:
命令会读取当前工作目录下的 .env,并覆盖已有的 Shell 环境变量,无需浏览器或设备。详见模型调试与可观测性。
Web 项目还需要安装 Chromium:
其他平台在创建时修改 --platform,并完成对应准备:
3. 运行生成的示例
五个平台的模板都使用在线 React TodoMVC,演示添加、删除和完成任务。运行测试的浏览器或设备需要能访问该网站。
Web 模板在每条用例前通过 todo.setup 打开 All 视图、清空页面存储并重新加载,使用 DOM 确认列表为空,再由 todo.seed 添加三个任务,第一条用例校验初始状态,第二条用 AI 删除和完成任务后校验结果;每条用例后由 todo.captureState 记录页面状态。Android、iOS、HarmonyOS 和桌面端模板使用 AI 添加三个任务、删除一个、完成另一个、切换到已完成筛选,并校验结果。修改任务前,这些模板先通过 todo.setup 打开 All 视图并等待输入框,再由 aiAssert 检查列表为空(包含已完成任务)且没有遮挡弹窗。已有任务会保留;检查失败时,请切换到 All 删除全部任务,或仅清除 TodoMVC 网站的数据,关闭遮挡弹窗后重新运行。模型或连接异常应先按报告中的原因排查。AI 检查可能误判,失败时请结合报告确认页面状态。所有模板均串行运行,首次用例失败即停止后续用例(test.bail: 1),同时正常保存报告、释放资源。
运行结束后,可以在 midscene_run/report/ 查看报告,了解各用例及步骤的执行结果。随后修改 cases/todo.yaml 编写自己的用例,可用操作及其参数以生成的 Node 说明书为准。
了解可用的测试操作
官方操作与按需扩展
Midscene Test 将每一种可在 YAML 中调用的能力称为 Node(节点)。
Node 既可以在用例的 steps 中调用,也可以在 beforeEach、afterEach 等生命周期钩子中调用,写法相同。
所有平台都提供以下常用能力:aiAct 根据自然语言操作界面,aiAssert 检查预期结果,aiWaitFor 等待可观察条件成立,wait 等待指定时长。
在这些通用能力之外,Midscene 还为各个平台预置了专用操作。例如:
- Web:
gotoUrl打开网页、setCookies设置 Cookie、setViewportSize调整浏览器视口大小。 - Android:
launch启动应用、back返回上一页、home返回主屏幕、runAdbShell执行 ADB 命令。
创建项目时,脚手架会根据选择的平台显式注册相应的官方 Node。手写 midscene.config.ts 时不会隐式注册任何 Node,需要自行配置。开发者也可以按需扩展,例如通过业务接口准备测试订单,详见注册自定义业务 Node。
生成当前项目的 Node 说明书
不同平台、执行项目和项目版本实际注册的 Node 可能不同。不要根据其他项目的示例推测当前项目的可用能力;midscene-test nodes 根据最终生效的注册结果生成 Node 说明书,它是当前项目可用 Node 名称、输入字段和字符串简写方式的事实来源。人类和 AI Agent 都应根据这份 Node 说明书编写 YAML 用例。
脚手架会在安装依赖后自动生成。修改 agentClass、顶层 nodes、projects[].nodes、Node schema,或者升级相关 Midscene 包后,应重新生成:
也可以直接运行命令,并指定测试目录、配置文件或执行项目:
配置了 projects 时,midscene-test nodes 默认按执行项目分别生成说明书,即使各项目的 Node 定义完全相同。文件名为 midscene-node-spec.<project-name>.md。使用 --project <name> 只生成指定项目的说明书,文件名保持一致。未显式配置 projects 时,文件名仍为 midscene-node-spec.md。文件写入指定目录;省略目录时写入当前目录。在 package.json 所在目录运行命令即可将说明书保存在该目录。Project name 重复,或转换后的文件名冲突(包括大 小写差异),都会在写入任何文件之前抛错。
生成命令只加载项目配置和 Node 定义,不执行 setup、用例或 getAgent,因此不需要启动浏览器、连接设备或调用模型。说明书是生成文件,不要手动编辑;配置变化后重新执行命令。
说明书包含两个部分:Available Nodes 列出可用 Node,Node Details 展示每个 Node 的 description、字符串简写规则和输入结构。输入结构由 Zod inputSchema 转换为标准 JSON Schema。说明书和终端输出均优先列出 aiAct、aiAssert,其余 Node 按名称排序。
说明书还会列出用例文件的匹配规则(Case files)和配置文件路径(Config file),方便用例编写者定位文件。Case files 对应各执行项目的 files.include 和 files.exclude。这两类路径均相对于说明书所在目录。
编写 YAML 测试用例
一个典型的 YAML 文件
一个 YAML 文件可以包含多个测试用例,以及用例执行前后的准备和清理步骤。下面以商城搜索为例:每次运行用例前打开首页,再搜索商品并检查结果。请将网址和商品名称替换为你的业务内容。
文件中各部分的含义如下:
beforeEach:每个用例执行前运行的步骤。它是可选的,适合打开页面、重置状态等准备操作。其他钩子见执行生命周期。cases:测试用例列表,至少包含一个用例。需要增加用例时,在列表中添加新的name和steps。name:用例名称,用于在运行结果中识别这个用例。steps:按顺序执行的步骤,至少包含一个步骤。每个步骤只能调用一个 Node,冒号后填写调用参数。
文档中把整个 YAML 文件称为 Workflow Document(工作流文档),把一个用例称为 Case,把一次 Node 调用称为 Step(步骤)。
示例使用字符串简写:gotoUrl 后的文本作为 url,aiAct 和 aiAssert 后的文本作为 prompt。需要传入更多参数时,可以使用下文的对象写法。是否支持简写,以项目的 Node 说明书为准。
关键 Node:操作与断言
日常用例主要通过 aiAct 描述操作,通过 aiAssert 检查结果:
操作完成不代表测试通过,应使用 aiAssert 明确检查预期结果。需要自定义断言失败信息时,可以展开参数:
aiAct 支持可选的 options.effort,用于选择规划投入程度:fast、balance 或 deepThink。省略时沿用 Agent 默认行为;同时提供 deepThink 时,effort 优先。例如:
设置 AI 上下文
推荐在 beforeAll 中调用 setAIContext,这样可以在当前文档的用例执行前统一配置上下文,让配置对后续使用同一个 Agent 的所有相关 AI 操作生效。也可以在 beforeEach 或用例的 steps 中调用,按需设置或清除上下文;修改从调用时开始生效 。
参数与 agent.setAIContext(target, context) 一致:target 可以是 default 或 aiAct、aiTap、aiAssert 等 AI API 名称。
设置 context:传入 context 字符串,设置对应 API 的上下文;使用 target: default 可以设置各 AI API 共用的默认上下文。
清除 context:省略 context,等同于传入 undefined,移除 target 对应的配置。
清除某个 API 的上下文后,该 API 会回退到 default;清除 default 则移除共用的默认上下文。如果需要禁用某个 API 继承的上下文,可以将其 context 设为空字符串 ""。
单次调用的 options.context 优 先于 Agent 级配置,各层上下文不会拼接。配置属于 Agent 实例:beforeAll 与用例需要使用同一个 Agent;修改会持续生效,直到被覆盖或清除。
其他 Node 的调用模式
平台操作和自定义业务 Node 使用相同的调用结构:Node 名称下面填写参数。下面展示多参数和无参数两种常见形式,这些片段可以放入用例的 steps 中:
setViewportSize 接收一个参数对象;clearCookies 无需参数,使用 {}。这两个 Node 由 Web 项目提供。移动端、桌面端以及团队自定义 Node 的可用范围和参数,以当前项目的说明书为准。
例如,如果团队注册了创建订单的 order.create,就可以这样调用。该 Node 是业务扩展示例,使用前需要在项目中实现和注册:
参数还可以包含嵌套对象或数组。比如给 aiAct 传入参考图时,文字和图片共同组成 prompt;options 则单独填写:
设置超时和错误处理
$ 用于设置由 Midscene Test 控制的 Step 参数。Midscene Test 不会将这些参数传入 Node 的 input。
支持以下两个字段:
timeout:Step 的超时时间,单位为毫秒。continue-on-error:设为true后,Step 失败时允许继续执行当前阶段的后续 Step。默认值为false。操作未退出或资源清理异常时,仍会停止执行。
continue-on-error 只控制 Midscene Test 是否继续执行。只要有 Step 失败,Case 的最终状态就是 failed。
超时不代表底层操作已 经退出。继续同阶段的后续 Step 前,框架会等待已取消的操作结束,默认最多 30 秒;仍未结束就停止后续步骤。等待单独计时,不占下一步的超时预算。操作结束后可以继续使用 Agent,但页面和业务状态仍需由用例确认或重置,见超时与取消机制。
使用项目变量与环境变量
Midscene Test 会在执行前递归解析 Node input:
${name}读取当前执行项目的variables;独占整个标量时保留原始 JSON 类型。${{ENV_NAME}}读取环境变量,结果始终是字符串。- 对象或数组变量可以作为完整值使用,但不能嵌入更长的字符串。
- 未定义变量会在收集阶段失败。变量只解析 Node input,不解析
$。
Workflow YAML 不提供 set、saveAs 或 Step 输出表达式。每个 Step 独立运行,不会自动接收前序 Step 的结果。如需共享必要信息,请通过执行项目的 context 显式提供。
使用 tags 筛选 Case
框架维护者在每个执行项目中配置 tags.include 与 tags.exclude。exclude 始终优先;include 非空时,Case 命中任意一个 include tag 即会被选中。
定义执行生命周期
beforeAll 在 setup、fileSetup(如配置)完成后执行,使用准备好的 context。三者区别见项目生命周期;本节介绍 YAML 钩子的用法。
准备与清理步骤
生命周期钩子用于在用例执行前后准备环境、重置状态或清理数据。四个钩子都是可选的,与 cases 同级;其中的步骤和用例 steps 使用相同的 Node 调用写法。
下面的 Web 示例在每个用例开始前打开商城首页,结束后清除 Cookie。data.prepare 和 data.cleanup 是需要由项目实现和注册的自定义 Node,分别准备和清理测试商品;gotoUrl、clearCookies、aiAct 和 aiAssert 是 Web 脚手架默认注册的官方 Node。请替换示例网址和商品名称。
执行顺序与重试
没有失败或重试时,上面文件的执行顺序为:
配置重试后,失败的用例会在本次清理完成、没有操作仍在运行时,在重试次数范围内重新执行 beforeEach → steps → afterEach,再继续后续用例。重试不会重新执行 beforeAll,afterAll 仍在文件结束时运行一次。重试次数是上限:操作未退出、清理等待或清理失败都会提前停止重试。
失败时如何执行
一个阶段中的步骤失败后,默认跳过该阶段的剩余步骤。设置 continue-on-error 可以继续,但结果仍为失败。清理 Node 应能处理准备只完成一部分的情况。
一个用例失败后,默认继续下一个用例。用 test.bail 设置失败用例数阈值后,达到阈值会跳过后续用例和重试;当前尝试完成后再清理。取消运行则会请求正在执行的操作退出。有依赖关系的业务步骤应放在同一个用例中。
资源故障或已登记的清理函数失败、未完成时,停止当前文件的重试 和后续用例。其他文件能否继续,取决于资源的共享范围:
普通 afterEach 步骤失败仍按用例失败处理;操作已退出且已登记的清理完成后,可以重试。报告写入等运行基础设施错误会取消整次运行。
资源配置见使用 setup 创建和清理共享资源,Node 内部的清理方式见资源的生命周期与清理。
运行测试
在项目根目录下,使用以下命令运行 YAML 测试用例:
指定用例目录或文件
生成的项目通过 files.include 选择 cases/ 下的 .yaml 和 .yml 文件。未配置 files 时,Midscene Test 会递归查找测试目录下的 YAML 文件,自动忽略 node_modules 和 .git。
如果你只想执行特定目录或特定用例文件,可以将其作为参数传入:

