Maa Node TestMaa 节点测试的 VS Code 插件,基于 功能
范围插件范围限于节点测试,输入为测试文件( 装之前
插件不改动被测仓库,也不往里加文件。 装正式版还没发布到市场。发布之后可以:
维护者发一版分两步(
标签由工作流自己打,不需要在本地 开发态想改代码或者还没发版时,用调试方式跑:
关键点:运行插件的那个窗口,工作区必须是被测的那个仓库。插件要靠它读 方式一(推荐):用多根工作区文件把 按 方式二:只开插件目录打开 方式三:直接在 MaaEnd 窗口里调试把这段加到
注意这是个人配置: 方式一、方式二按 怎么用测试面板左侧活动栏的烧瓶图标(测试):
失败信息分两层:节点上显示一行短标题,点开测试结果看到明细列表。例如只在 CloudADB 上失败时:
文件节点上是「2 条用例失败」,展开后逐条列出每条用例的原因,省得一条条重跑。 测试输出:先看末尾那块「结果」「测试输出」分两段,顺序就是读的顺序:
文件里的运行按钮(CodeLens)打开任意
跑完会进「Maa 节点测试」输出面板,并按结果弹提示(通过 / 失败 / 没跑起来 / 没有匹配用例)。 鼠标放在
|
| 命令 | 作用 |
|---|---|
Maa 节点测试: 运行当前测试文件 |
跑当前文件所有用例 |
Maa 节点测试: 运行当前测试用例 |
先弹用例列表让你选 |
Maa 节点测试: 查看当前测试文件的运行计划(不实际执行) |
dry-run:只解析、过滤、检查截图,不加载 MaaFW |
Maa 节点测试: 刷新测试面板 |
手动重扫测试文件 |
设置项
| 设置 | 默认值 | 说明 |
|---|---|---|
maaNodeTest.nodePath |
node |
跑测试用的 node。要求 22+;不在 PATH 里就填绝对路径 |
maaNodeTest.configPath |
maatools.config.mts |
maa-tools 配置文件,相对工作区根。用来认定哪个工作区文件夹是「仓库根」 |
maaNodeTest.testsetDir |
tests/MaaEndTestset |
截图根目录,相对工作区根。悬浮预览按它扫描平台目录 |
maaNodeTest.hoverImageWidth |
400 |
悬浮里预览图的显示宽度(像素)。0 表示按原图尺寸 |
maaNodeTest.hitsInlayHints |
true |
是否在 hits 的节点名后面显示注释(内联提示) |
常见问题
测试面板是空的。
当前窗口的工作区不是被测仓库,或者仓库里没有 tests/**/test_*.json。按上面的方式一重新打开。
调试窗口(F5)起来十来秒就整个关掉,控制台没有任何报错。
在远端(Remote-SSH)调试时遇到过:扩展开发宿主窗口在启动 9~15 秒后整个消失,服务端日志里只有一句 Extension Host Process exited with code: null, signal: SIGABRT,客户端和服务端都不留下任何 JavaScript 报错。一天里统计到 47 次调试窗口启动、8 次这样死掉(约六分之一)。
跟本插件无关,锅在 node 自带的事件循环库 libuv 里。崩溃栈是:
libc`abort
libc`__assert_fail
node`uv__io_poll(...) at linux.c:1427
node`uv_run(...)
libuv 给某个文件描述符注册监听时,内核回的不是「已经注册过」(EEXIST)而是 EBADF(这个描述符已经失效),libuv 没做降级处理,assert 一失败就把整个进程 abort 掉。用 eBPF 抓到的现场是 EPOLL_CTL_ADD fd=76 errno=9,而 fd 快照显示 76 号在被关闭前是个 socket —— 也就是有代码把一个还在被监听的 socket 提前关了。libuv 上游 [issue #5129](https://github.com/libuv/libuv/issues/5129) / #5130 说的就是这个问题,但修复没有进 1.x 分支。
已经排除的:本插件(崩溃那个窗口里它的输出通道是 0 字节,代码纯 JS,没有任何能发出 SIGABRT 的调用)、nekosu.maa-support、vadimcn.vscode-lldb、ms-vsliveshare.vsliveshare,以及「挂着调试器」(Ctrl+F5 不挂调试器也会崩)。
临时办法:.vscode/launch.json 里选「只加载本扩展(调试窗口会闪退时用)」,它带 --disable-extensions,调试窗口里只加载本插件 —— 少了其它扩展的 socket 增删,能降低概率但不是根治。崩了就重开,插件本身的功能不受影响。
自己往下查的话:服务端日志在 ~/.vscode-server/data/logs/<时间戳>/remoteagent.log(搜 SIGABRT),宿主细节在同目录 exthost<N>/remoteexthost.log;想拿原生调用栈就开 core(kernel.core_pattern + prlimit --core=unlimited),然后用 vadimcn.vscode-lldb 自带的 lldb 读;想抓 errno 用 bpftrace 而不是 strace(strace 会把进程拖慢,反而让这种时序问题消失)。完整步骤记在 .agents/notes/implemented/process/2026-10-27-dev-host-sigabrt.md。
点运行,提示「没跑起来」。
大多是 node 版本低于 22,用 maaNodeTest.nodePath 指到 22+ 的 node。也可能是第一次运行要联网下载 MaaFW 失败,看「Maa 节点测试」输出面板里的 prepare 日志。
提示「没有匹配到任何用例」。
configs.controller 或 configs.resource 写得不在 tests/scripts/loader.mts 的映射里。命令面板的「查看运行计划」能看出到底解析出了哪些组。
声明的平台缺截图会怎么提示?
四个地方都会提示,缺图不会被当成「通过」糊过去:
- 写的时候(不用跑):
image的值下面一条黄色波浪线,说明哪个平台没这张图、哪个平台连目录都没有;测试面板的用例节点上带一句「缺 ADB 截图」; - 悬浮里那个平台直接标
缺失;声明了、但测试集里连平台目录都没有,会写「tests/MaaEndTestset下没有这个平台的目录」; - 运行日志里先打一块「平台覆盖」:每个平台多少张截图、缺几张,以及声明了却没匹配到测试组的平台(通常说明 controller 名字写错或
tests/scripts/loader.mts没映射它); - 测试面板里那条用例标成跳过(灰的,不算失败),文件节点仍算通过,但会带一句「N 条用例没有验证到(缺图跳过,不算失败,补图后重跑即可)」并在测试输出里列出是哪几条 —— 因为
maa-tools遇到缺图只会跳过,跳过在它那里等于通过,插件把它显式顶出来,同时不把整次运行染红。
为什么全量跑要几分钟?
节点测试本身就是几百上千次识别,时间花在识别上,不是插件。插件已经把「一个文件一个进程」改成「一批文件一个进程」,和 pnpm test 的速度基本一致;机器核越多越快(maa-tools 默认开 核数/4 个 worker)。
悬浮里的图片不显示。
远程 / WSL / 虚拟工作区下 file:// 可能加载不出来,点「打开原图」看。
改了测试文件没生效。
面板和运行都读磁盘上的文件,先保存(Ctrl+S)。
已知限制
- 两条用例共用同一张截图、同一批节点时,会被同时点名:结论按「图片 + 期望命中的节点」归位,这种情况区分不了。
- 缺图的用例在
maa-tools里算通过:它遇到不存在的截图只打印跳过。插件不改它的判定,但会在悬浮、运行日志(平台覆盖)和测试面板(用「跳过」而不是绿勾,也不算失败)三处显式提示。 - 逐用例原因依赖 maa-tools 的错误明细:它写
tests/maatools/error_details.json,插件只在本次运行确实更新过这个文件时才采信;拿不到就退化成「整个文件失败,原因未知」。 - 悬浮图片按原尺寸渲染:图大时悬浮框会很高。
和具体仓库的关系
插件是独立的(自己一个仓库、自己一套构建),不塞进被测仓库:那边 CI 只为 Pipeline / 资源 / Agent 服务,加一个需要 tsc 构建的 VS Code 扩展会平白多一套构建产物和依赖。
它对被测仓库的假设只有三条:
- 工作区根有
maatools.config.mts(maa-tools的默认约定); - 测试文件叫
tests/**/test_*.json(同上); - 截图按
<控制器>/<资源服>/<图片>分目录放在测试集里。默认路径是tests/MaaEndTestset(MaaEnd 的写法),别的仓库用maaNodeTest.testsetDir指过去。
补全和缺图检查都读 tests/scripts/loader.mts 里的 controllerMap / resourceMap:那是「测试文件里写的名字 → 截图目录名」的唯一依据。没有这个文件时,插件按同名处理,补全只给测试集里扫到的平台目录名。
图标 icon.png 用的是 MaaEnd 项目的 logo(512×512)。fork 之后要换成自己的图标,直接替换这个文件即可。
默认值来自 MaaEnd 纯粹是因为作者日常在测它。换一个仓库来用,一般只需要改 maaNodeTest.testsetDir 和 maaNodeTest.configPath;如果那个仓库的 tests/scripts/loader.mts 用了不一样的组名拼法,插件靠「组名 + 用例键」把用例从全量结果里挑出来这一步也要跟着调(见 reference.md)。
想改这个插件
- 常用命令:
pnpm run check(类型检查)、pnpm run build(编译 + 打包到dist/)、pnpm test(扩展单测)、pnpm run test:runner(runner 单测)、pnpm run test:all、pnpm run package(打 VSIX); - AGENTS.md:项目边界、代码地图、硬约束;
- .agents/skills/maa-node-test-dev/SKILL.md:改这个插件时的操作手册;同目录 reference.md 是命令行契约、退出码映射、内部实现细节;
- .agents/notes/:设计取舍记录(为什么自带 runner、为什么独立成仓、为什么合成一批跑)。
致谢
- neko-para/maa-support-extension:本插件的参考实现,扩展的组织方式、悬浮与补全里显示节点注释的写法都来自它;它的
@nekosu/maa-tools还直接提供了节点测试的执行能力(loadConfig/runTest/loadAllTestCases),插件自己不实现识别与比对。 - MaaXYZ/MaaFramework:节点(Pipeline)协议与识别算法,节点测试跑的就是它。
- MaaEnd/MaaEnd:节点测试的用例格式、
tests/MaaEndTestset的测试集目录约定、tests/scripts/loader.mts里的控制器与资源映射;插件的默认值和图标都取自这个仓库。 - he0119/vscode-bangumiplan:发布流程的参考,测试/发布两个 workflow 的结构(vsce 发布、Open VSX、GitHub Release 附件)照它配的。
License
MIT