配置测试工程
midscene.config.ts 是 Midscene Test 的工程配置文件。你可以在其中定义浏览器或设备的初始化逻辑、注册供 YAML 调用的 Node,以及设置并发数、超时时间等运行参数。本文介绍配置文件的基本结构、Agent 与各平台接入方式、多执行项目(Project)管理,以及文件级资源隔离。
配置文件结构
测试工程通过 defineTestProject() 定义并导出配置。Midscene Test 支持以下配置文件格式与加载方式:
默认情况下,Midscene Test 会在测试根目录下查找 midscene.config.ts 或 midscene.config.mjs。如果两个文件同时存在,框架会直接报错提示冲突,而不会静默选择其中一个;此时可通过 --config <路径> 明确指定要使用的配置文件。
核心配置项如下:
下文先以单个执行项目为例说明如何配置运行环境。如果需要管理多个执行项目,或为不同项目注册各自的 Node,请参阅配置多个执行项目。
配置运行环境
完整示例:Playwright
下面是一个仅使用 setup 的串行配置示例:同一个执行项目中的所有 YAML 文件共用同一个浏览器页面。如果希望每份 YAML 文件使用相互隔离的浏览器上下文,可以配合使用 fileSetup(无需开启并发即可使用)。
如果要在已有工程中手动接入 Web 测试,请先安装依赖:
运行测试前,还需按照使用 模型 API Key配置模型环境变量。如果你将模型配置保存在 .env 文件中,手写 midscene.config.ts 时需要自行加载(例如安装 dotenv 并在配置文件顶部引入 import 'dotenv/config'),或者直接通过 Shell / CI 注入环境变量,详见加载环境变量。
在这个配置中,各部分的职责与协作关系如下:
setup:启动浏览器并创建页面,同时通过onTeardown()注册资源清理函数。context:保存运行期上下文。Node 调用getAgent获取 Agent 实例——首次调用时创建PlaywrightAgent并缓存到context.agent中,后续步骤直接复用该实例及其关联的page。nodes:注册通用 AI 操作和 Playwright 平台操作,供 YAML 用例调用。projects:声明名为chromium的执行项目,将playwrightSetup与cases/目录下的 YAML 用例关联起来。
完成上述配置后,即可开始编写 YAML 用例并运行测试。下面进一步说明如何管理资源的共享与隔离。
使用 setup 创建和清理共享资源
defineProjectSetup() 用于定义执行项目(Project)级别的初始化逻辑,并挂载到 setup 字段上。测试运行时,每个执行项目只会调用一次自身的 setup(),返回的对象将作为共享上下文供该项目内的步骤使用。
如果你希望每个 YAML 文 件拥有独立的运行环境,可以使用 defineFileSetup() 定义文件级初始化逻辑,并挂载到 fileSetup 字段上。fileSetup 会接收项目级 setup 的返回值,在此基础上为当前文件创建独立资源,详见下一节用 fileSetup 隔离资源。
注意,setup 创建的共享资源不会在每条用例开始前自动重置。如需在用例间重置页面、Cookie 或业务状态,请在 YAML 的生命周期钩子中调用相应的 Node;自定义 Node 之间读写共享数据的方式请参阅跨 Node 共享上下文。
创建 Browser、Agent 等资源后,应立即通过 onTeardown() 注册清理函数。即便 setup 过程或用例执行失败,框架也会在执行项目结束时逆序(后进先出)调用已注册的清理函数——例如在上面的 Playwright 示例中,会先销毁 agent,再关闭 browser。注意,在 setup 中注册的 onTeardown() 仅在整个执行项目结束时触发;而在自定义 Node 内部注册的 onTeardown() 则具有独立的清理时机。
用 fileSetup 隔离资源
当多个 YAML 文件需要隔离运行环境(或开启文件并发)时,可以用 setup 准备项目级共享资源,再用 fileSetup 为每个文件创建独占资源。例如在 Web 测试中,可以让整个项目共享同一个 Browser 进程,而 为每个 YAML 文件单独创建 BrowserContext、Page 和 Agent,从而隔离各文件之间的 Cookie 与本地存储:
对应的 YAML 文件直接使用 fileSetup 准备好的 Agent,在 beforeAll 中设置视口大小,在 beforeEach 中为每条用例打开首页:
在这个示例中,每个 YAML 文件执行完毕后会依次销毁自身的 Agent 并关闭 BrowserContext;当该项目的所有文件均清理完毕后,才会关闭项目级共享的 Browser。
defineFileSetup<FileContext, SharedContext> 的两个泛型参数分别代表文件级 context 类型和项目级 projectContext 类型。注意:fileSetup 的返回值会直接作为该文件的完整 context 传给 Node,框架不会将它与 projectContext 自动合并;如果 Node 需要访问 projectContext 中的字段,请在 fileSetup 的返回对象中显式透传。
fileSetup 的 setup 函数接收以下参数:
如果工程只有一组环境配置,可以省略 projects 数组,直接将 setup 和 fileSetup 写在顶层配置中;如果每个文件能独立完成所有资源初 始化,也可以只配置 fileSetup 而不配置 setup。
对于 Android、iOS 等移动端或桌面端平台,若要开启文件并发,必须为每个并发文件分配独占的物理设备或模拟器,并分别创建独立的 Device 和 Agent。每个 Device 实例只能归属于一个 Agent,调用 Agent.destroy() 时会一并销毁其关联的 Device,因此设备归还逻辑应当排在 Agent 销毁之后。如果你手头只有一台测试手机或一个桌面环境,请将该项目的并发上限设为 1,否则多个 Agent 同时操作同一台设备会互相干扰。
关于文件环境的共享范围与清理顺序,请参阅生命周期与并发;关于初始化失败后的调度行为,请参阅失败时如何执行。此外,如果项目级共享资源(如共享 Browser)在运行期间意外不可用,应在 fileSetup 或自定义 Node 中显式标记共享资源错误,框架不会仅凭浏览器关闭的报错文本自动推断,详见异步操作、错误与取消。
注册官方 Node
通用 AI 操作与 Agent 接入
Midscene Test 内核不会隐式注册任何 Node。使用 midscene-test create 创建项目时,生成的配置文件会调用 @midscene/test/midscene 导出的 createMidsceneNodes() 来注册 所选平台的官方 Node。如果你手写配置文件,需要将 createMidsceneNodes() 返回的数组显式传入顶层 nodes 或 projects[].nodes 中才会生效:
调用 createMidsceneNodes() 时需传入两个核心参数:
agentClass:指定平台对应的 Midscene GUI Agent 类(必须实现getTestRunnerNodeDefinitions(),否则会在注册阶段报错)。传入PlaywrightAgent、PuppeteerAgent、AndroidAgent、IOSAgent或HarmonyAgent(及其 Page/Browser 变体)时,会同时导出通用 AI Node(如aiAct、aiAssert、数据提取、视觉定位等)、内置waitNode 以及该平台专属的操作 Node;而基础Agent和ComputerAgent则提供通用 AI Node 与wait。getAgent:声明在步骤执行期间如何从当前context中获取 Agent 实例(context的具体字段结构由你自行定义)。
在 Android、iOS 等移动端平台接入 Agent 时,请注意 Device 的生命周期约束:每个 Device 实例只能绑定给一个 Agent,调用 Agent.destroy() 时会自动销毁该 Device。因此,请为每个 Agent 创建独立的 Device 实例,切勿在 Agent 销毁后复用同一个 Device。
注册完成后,即可在 YAML 用例中直接调用这些官方 Node。完整的可用 Node 名称与参数字段,请以当前项目生成的 Node 说明书为准。
为多个 Midscene Agent 的 Node 命名
同一个工作流使用多个 Midscene Agent 时,可以通过 namespace 为各组 Node 注册不同的名称。让 setup 在 context 中返回独立的 Midscene Agent 实例,再将两组 Node 注册到同一个 Project:
将 nodes 加入项目配置后,YAML 使用注册后的名称调用:
namespace 会给返回的每个 Node 加上前缀,包括通用 AI 操作、平台操作和 wait。例如,上述注册提供 mobile.aiAct 和 mobile.wait,不会同时注册不带前缀的名称。不传 namespace 时保留原有名称。
namespace 必须是非空字符串,不能包含空白字符、首尾的点或空的分段;支持 checkout.mobile 这样的嵌套名称。无效值会在注册阶段报错,此时尚未获取 Agent。
namespace 只改变 Node 名称。运行时仍由 getAgent 或 agentProvider.getAgent 选择 Agent,执行记录仍关联到对应 Step。namespace 不创建资源,也不提供并发隔离。不同 Project 可以分别注册相同的 Node 名称,无需添加 namespace。
Playwright
通过 createMidsceneNodes({ agentClass: PlaywrightAgent, getAgent }) 会自动注册 Web 专属的 gotoUrl、setCookies、clearCookies 和 setViewportSize 四个 Node。使用前需在项目中安装同级依赖 playwright:
安全设置 Cookie:调 用 setCookies 时,不支持在 YAML 中直接明文填写 Cookie 值。这是因为 Midscene Test 会将 Node 的输入参数记录到运行结果文件中,明文填写会导致敏感凭证泄露。
你必须在 cookiesEnv(环境变量名)、profile(预置配置名)或 storageStatePath(Playwright 状态文件路径)三者中任选其一,以引用方式传入 Cookie。setCookies 仅在执行瞬间读取真实 Cookie 并注入 BrowserContext。成功时的输出记录引用名称和 Cookie 条数。失败时,底层错误可能包含 Cookie 值。
关于 Cookie 引用的补充说明:
- 环境变量默认从
process.env读取,内容可以是Cookie请求头字符串、Cookie JSON 数组或 PlaywrightstorageStateJSON。 - 相对路径的
storageStatePath默认相对于当前工作目录解析。如需自定义环境变量读取、Profile 映射或路径解析逻辑,可在实例化 Agent 时通过testRunner选项传入getEnv、getCookieProfile或resolveStorageStatePath回调(回调中的context为当前 Agent 实例)。 - 请妥善保管环境变量、Profile 和
storageState文件,切勿将包含真实 Cookie 的文件提交到代码仓库。
Puppeteer
Puppeteer 同样提供同名的 gotoUrl、setCookies、clearCookies 和 setViewportSize Node,参数结构与 Cookie 引用方式与 Playwright 完全一致。使用时需安装 puppeteer 并将 PuppeteerAgent(或 PuppeteerBrowserAgent) 传给 createMidsceneNodes():
为了方便同一份 YAML 用例在 Playwright 和 Puppeteer 之间平滑切换,gotoUrl.waitUntil 推荐使用跨浏览器通用的 domcontentloaded、load 或 networkidle(Puppeteer 适配层会自动将 networkidle 映射为 networkidle0)。两者的专有枚举值(Playwright 的 commit,Puppeteer 的 networkidle0 与 networkidle2)仍可在各自驱动下使用,但跨驱动混用时会直接报错。此外,调用 gotoUrl 传入相对路径时,会优先基于 testRunner.baseURL 解析;若未配置 baseURL,则基于当前页面的 HTTP(S) 地址解析。
Android
接入以下移动端平台时,请在 ProjectContext 中声明对应平台类型的 agent,并在 setup 返回的对象中提供该实例。
使用 createMidsceneNodes({ agentClass: AndroidAgent, getAgent }) 会注册 Android 专属的 launch、terminate、runAdbShell、back、home 和 recentApps:
runAdbShell 的完整命令输出会保存在该步骤的执行结果中。
iOS
使用 createMidsceneNodes({ agentClass: IOSAgent, getAgent }) 会注册 iOS 专属的 launch、terminate、runWdaRequest、home 和 appSwitcher:
runWdaRequest 的完整响应数据会保存在该步骤的执行结果中。
HarmonyOS
使用 createMidsceneNodes({ agentClass: HarmonyAgent, getAgent }) 会注册 HarmonyOS 专属的 launch、terminate、runHdcShell、back、home 和 recentApps:
runHdcShell 的完整命令输出会保存在该步骤的执行结果中。
配置执行项目
执行项目(Project)用于将特定的运行环境与一组测试用例绑定。即便工程里只有一个执行项目,你也可以在其中配置用例筛选规则、项目变量和失败重试次数;当需要在不同浏览器、设备或环境上运行测试时,则可以在 projects 数组中声明多个执行项目。
选择用例与控制执行
脚手架生成的配置默认匹配 cases/**/*.{yaml,yml};如果未配置 files,Midscene Test 会按 **/*.{yaml,yml} 在测试根目录下递归查找用例文件,自动去重并按路径排序。
关于如何通过命令行筛选运行目标,请参阅运行测试;单个步骤的超时与容错配置请参阅设置超时和错误处理;执行顺序、重试与并发规则请参阅生命周期与并发。所有执行项目的运行结果最终都会汇总生成一份统一的 HTML 报告,查看与归档方式见运行测试。
配置多个执行项目
当需要在多个平台或设备上运行测试时,可以在 defineTestProject() 的 projects 数组中配置多个执行项目。
在顶层 nodes 中注册的 Node 对所有执行项目全局生效(省略时默认为 [])。同时,每个执行项目也可以通过自身的 nodes 字段注册项目级 Node——项目级 Node 仅对当前项目生效,若与全局 Node 同名则会覆盖全局定义。注意,在同一层级内重复注册同名 Node 会直接报错。
例如,同时配置 Android 和 iOS 两个执行项目时,可以将跨端通用的业务 Node 放在顶层 nodes,而在各自项 目中分别注册对应平台的官方 Node:
通过这种方式,两个执行项目可以复用同一份 YAML 用例文件:在收集用例、校验参数和实际执行时,launch 等同名平台 Node 会自动绑定到当前项目注册的实现上,互不干扰。
为各项目生成 Node 说明书
运行 midscene-test nodes 可以根据项目的注册配置生成 Node 说明书。传入 --project 参数时,生成的说明书会列出该执行项目合并全局与项目级 Node 后最终生效的完整列表:
如果配置了 projects 且未传入 --project 参数,命令默认会为每个执行项目分别生成一份独立的说明书。关于文件命名规则与说明书结构,请参阅

