YAML 脚本运行器
本文档介绍的是老版 YAML 自动化运行方案。我们已推出了全新、面向未来的 Test Runner (Beta)。
新方案采用“自然语言驱动主线,可编程可定制 Node 作为辅助”的全新测试范式,支持完备的测试生命周期、多环境并发隔离以及标准化运行报告,是老版方案的官方替代升级版。
目前新方案正处于 Beta 开放阶段,我们强烈建议您阅读 Test Runner 概览 并基于新方案进行项目实践与迁移。
Midscene 定义了一种 YAML 格式的脚本,方便开发者快速编写自动化脚本,并提供了对应的命令行工具来快速执行这些脚本。
举例来说,你可以编写如下 YAML 格式脚本示例:
并通过一条命令来 执行它:
命令行会输出执行进度,并在完成 后生成可视化报告。整个运行过程大幅简化了开发者做环境配置的复杂度。
本文将介绍如何使用 Midscene 的命令行工具。关于更多 YAML 格式脚本的内容,可以参考 使用 YAML 格式的自动化脚本。
使用 .env 配置环境变量
Midscene 命令行工具使用 dotenv 来加载 .env 文件。你可以在工具运行目录下创建一个 .env 文件,并添加以下配置:
支持的模型和完整配置示例请参考支持的模型与配置。
请注意:
- 这个文件不是必须的,你也可以通过全局环境变量的形式来配置
- 请注意这里没有
export前缀,这是 dotenv 库的约定 .env文件必须放置在工具运行目录下,而与 YAML 文件所在的目录无关。- 这些变量默认是不覆盖全局环境变量中已经的同名变量的,如需修改这个策略,请参 考后文“--dotenv-override” 参数
- 如需调试此部分环境变量的逻辑,可使用
--dotenv-debug参数
开始使用
安装命令行工具
安装 CLI 前,请确认运行 midscene 的终端使用 Node.js 20.19+、22.12+ 或 24+。CLI 的部分执行路径会使用 Rstest/Rspack 工具链,这些依赖会拒绝 20.17.0 这类较旧的 Node 20 patch 版本。如果看到 Rspack 抛出的 Unsupported Node.js version 提示,请升级 Node.js 后重新安装全局 CLI 或项目依赖。
全局安装 @midscene/cli (推荐新手使用):
或在项目中按需安装
编写第一个脚本
编写一个名为 bing-search.yaml 的文件来驱动 Web 浏览器:
驱动已连接 adb 的 Android 设备:
或者驱动配置好 WebDriverAgent 的 iOS 设备:
运行脚本
命令行会输出执行进度,并在完成后生成可视化报告。
命令行工具的高级用法
在 .yaml 中使用环境变量来填入动态值
脚本中可以通过 ${variable-name} 引用环境变量。环境变量会在 YAML 任务执行前完成替换,包括任务正文中的字符串。
运行多个脚本
@midscene/cli 支持使用通配符匹配多个脚本来批量执行脚本,这相当于 --files 参数的简写。
分析命令行运行结果
执行完成后,输出目录会包含:
--summary指定的 JSON 报告(默认index.json),记录所有脚本的执行状态与统计数据。- 每个 YAML 文件对应的独立执行结果(JSON 格式)。
- 每个脚本生成的可视化报告(HTML 格式)。
运行在可视化(Headed)模式
仅适用于 Web page 场景
Headed 模式会打开浏览器窗口。默认情况下脚本在无头模式运行。
使用 CDP 连接模式
仅适用于
web场景
CDP 模式可以让 YAML 脚本通过 Chrome DevTools Protocol 连接到已有的浏览器实例,无需启动新浏览器。适用于需要复用已有浏览器会话、连接远程浏览器或云端浏览器服务的场景。
在 page 配置中设置 cdpEndpoint:
CDP 模式与桥接模式互斥,不可同时使用。CDP 模式下 Midscene 只会断开连接(disconnect),不会关闭浏览器。
使用桥接模式
仅适用于 Web page 场景
使用桥接模式可以让 YAML 脚本驱动现有的桌面浏览器,便于复用 Cookies、插件或已有状态。先安装 Chrome 扩展,然后在 page 配置中加入:
更多细节请参阅 通过 Chrome 插件桥接模式。
使用 JavaScript 运行 YAML 脚本
调用 Agent 的 runYaml 方法同样可以在 JavaScript 中执行 YAML,注意该方法只会运行脚本中的 tasks 部分。
命令行参数
命令行工具提供了多项参数,用于控制脚本的执行行为:
--files <file1> <file2> ...:指定脚本文件列表。默认按顺序执行(--concurrent为1),可通过--concurrent设置并发数量。支持 glob 通配符语法;当 glob 或目录匹配到多个文件时,匹配结果会按文件路径的字典序排序后加入执行列表。--setup <file>:在主--files之前执行的前置脚本,适用于所有受支持的 target。如果所有 setup attempt 都失败,整个批次会被中止,主脚本将被标记为未执行。Puppeteer Web setup 必须配合--share-browser-context使用;此时每次 retry 都从全新的 BrowserContext 和 Page 开始,成功 attempt 的上下文会共享给主脚本。每个 YAML 仍在独立 Page 中运行,因此sessionStorage等页面级状态不会在脚本间传递。桥接模式和非 Web target 必须省略--share-browser-context;它们在 retry 时会创建新的 player 和 Agent,但不会重置底层浏览器、设备、桌面或外部 Interface 的状态。--concurrent <number>:设置并发执行的数量,默认1。--continue-on-error:启用后,即使某个脚本失败也会继续执行后续脚本。默认关闭。--retry <number>:失败脚本的额外尝试次数。只有失败的脚本会被重试,可缓解网络波动或大模型输出不稳定导致的偶发失败。默认0。Puppeteer Web setup retry 使用全新的 BrowserContext 和 Page,主脚本 retry 则保留成功的 setup 上下文。其他 target 每次 retry 会创建新的 player 和 Agent,但不会重置底层运行环境。--share-browser-context:在多个 Puppeteer Web 脚本之间共享同一个 BrowserContext(Cookies、同源localStorage等),同时每个 YAML 使用独立 Page。即使--concurrent 1,sessionStorage、DOM、URL、window.name等页面级状态也不会共享。同一批次中的 setup 和主脚本必须全部使用 Puppeteer Web target;不支持桥接模式和非 Web target。由于 Browser 只会创建或连接一次,浏览器级选项(cdpEndpoint、chromeArgs、acceptInsecureCerts和downloadPath)必须放在批次配置的全局 Web target 中,不能放在单个 setup 或主脚本中。默认关闭。--summary <filename>:指定生成的 JSON 总结报告路径。--headed:在带界面的浏览器中运行脚本,而非默认的无头模式。--keep-window:脚本执行完成后保持浏览器窗口,会自动开启--headed模式。--config <filename>:指定配置文件,文件中的参数会作为命令行参数的默认值。--web.userAgent <ua>:设置浏览器 UA,覆盖所有脚本中的web.userAgent。--web.viewportWidth <width>:设置浏览器视口宽度,覆盖所有脚本中的web.viewportWidth。--web.viewportHeight <height>:设置浏览器视口高度,覆盖所有脚本中的web.viewportHeight。--android.deviceId <device-id>:设置安卓设备 ID,覆盖所有脚本中的android.deviceId。--ios.wdaPort <port>:设置 WebDriverAgent 端口,覆盖所有脚本中的ios.wdaPort。--ios.wdaHost <host>:设置 WebDriverAgent 主机地址,覆盖所有脚本中的ios.wdaHost。--dotenv-debug:开启 dotenv 的调试日志,默认关闭。--dotenv-override:允许 dotenv 覆盖同名的全局环境变量,默认关闭。
示例:
使用 --files 指定执行顺序:
以 4 个并发执行多个互不依赖的搜索脚本,并在出错时继续运行:
通过文件编写命令行参数
可以把参数写到 YAML 配置文件中,并通过 --config 引用。命令行传入的参数优先级高于配置文件。
运行方式:
当脚本必须严格按照 files 列表的顺序执行时,请设置 concurrent: 1(默认值)。
当该值大于 1 时,执行顺序不确定;脚本不得依赖其他脚本的启动或完成顺序。
在并行脚本之前执行前置任务
当多个互不依赖的 Puppeteer Web 脚本都依赖同一个前置条件(例如登录)时,可以把前置任务写在 setup 下。前置脚本会在主 files 之前执行;成功后,主脚本再按配置的并发数运行。设置 shareBrowserContext: true 后,成功 setup attempt 的浏览器上下文(包括 Cookies 和同源 localStorage)会被主脚本复用。每个脚本使用独立 Page,因此 setup Page 的 sessionStorage、DOM、URL、window.name 和其他页面级状态不会复制到主 Page。同一共享批次中的所有脚本都必须使用 Puppeteer Web target,不支持桥接模式。
共享 Browser 只会根据批次配置创建或连接一次。请在批次配置 的全局 Web target 中设置 cdpEndpoint、chromeArgs、acceptInsecureCerts 和 downloadPath。如果在单个 setup 或主脚本中定义这些浏览器级选项,CLI 会直接报错,因为它们无法应用到已经创建的共享 Browser。
retry 表示额外尝试次数,因此 retry: 2 最多会执行三次。每次 setup retry 都会创建新的 BrowserContext 和 Page,避免失败 attempt 留下的 Cookies、localStorage、页面导航状态及其他浏览器副作用污染下一次尝试。setup 成功后,其上下文会与主脚本共享;主脚本失败时会在同一上下文中重试,从而保留成功 setup 建立的状态。如果所有 setup attempt 都失败,整个批次会被中止,主脚本将被标记为未执行。
shareBrowserContext 遵循浏览器原生的存储边界,不会在 Page 之间复制或同步 sessionStorage。如果 setup 只把登录态写入 sessionStorage,主脚本将无法继承该登录态。需要让多个脚本看到前置状态时,请优先使用 Cookies、同源 localStorage 或服务端状态。脚本并发运行时,共享状态的写入可能发生竞争,需要显式协调。
setup 也支持桥接模式、Android、iOS、HarmonyOS、Computer 和自定义 Interface target。这些 target 应省略 shareBrowserContext。retry 会创建新的脚本 player 和 Agent,但不会自动重置底层浏览器配置、设备、桌面会话或自定义 Interface;如果 retry 必须从干净环境开始,需要由 setup 脚本显式恢复环境。
常见问题
如何导出 JSON 格式的 Cookies?
可以借助 Chrome 扩展 导出 Cookies。
如何查看 dotenv 的调试日志?
使用 --dotenv-debug 参数即可:

