配置测试工程
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 引用的补充说明:
- 环境变量默认从
process.env读取,内容可以是Cookie请求头字符串、Cookie JSON 数组或 PlaywrightstorageStateJSON。 - 相对路径的
storageStatePath默认相对于当前工作目录解析。如需自定义环境变量读取、Profile 映射或路径解析逻辑,可在实例化 Agent 时通过testRunner选项传入getEnv、getCookieProfile或resolveStorageStatePath回调(回调中的context为当前 Agent 实例)。 - 引用机制仅用于防止 Cookie 被写入 Midscene Test 的持久化结果中;环境变量、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:

