如何测试功能
本文档区分编辑器检查、资源加载、文档构建和模拟器端到端验收。各项检查覆盖的范围不同,资源加载成功不代表任务可用。
测试方式总览
| 方式 | 适用场景 | 边界 |
|---|---|---|
| 编辑器静态检查 | JSON 语法、已配置 Schema 的字段诊断 | 不连接游戏,不验证识别或动作 |
| VSCode Maa 插件调试 | 单节点识别、截图、ROI 和取色 | 需配置工具及设备,不能替代完整任务验收 |
| 资源校验脚本 | 调用 MaaFramework 加载资源包 | 不导入 Python 自定义扩展,不启动任务 |
| 文档构建 | Markdown/MDX、文档路由及构建期诊断 | 不测试游戏功能 |
| MaaDebugger | 可选的独立调试工具 | 不在项目依赖中,需另行准备兼容版本 |
| 手动运行验证 | 在 MFAAvalonia 和真实模拟器中验证任务 | 覆盖正常流程、停止与异常场景 |
当前没有正式的 pytest/unittest 测试套件、覆盖率门禁或 npm test 命令。不要将后文的手动验收和资源加载称为单元测试通过。
方式一:VSCode Maa Pipeline Support 插件(推荐)
项目开发文档推荐使用 VSCode 插件 nekosu.maa-support 进行 Pipeline 调试。插件能力与操作入口以所安装版本的说明为准。
安装
在 VSCode 扩展市场安装 Maa Pipeline Support。
配置
按照插件文档配置 MaaFramework、资源目录和 ADB 控制器,资源目录使用 assets/resource/base。本文不约定插件配置文件的名称或格式,避免把特定版本的配置当成项目接口。
先处理编辑器报告的 JSON 语法错误;若已配置匹配当前 MaaFramework 版本的 Schema,再检查字段诊断。静态检查不会运行识别、自定义动作或游戏任务。
调试 Pipeline 节点
- 打开要修改的 Pipeline JSON 文件,确认插件已载入对应资源。
- 连接模拟器,将游戏停在待验证的画面。
- 使用插件当前版本提供的节点调试入口,先验证 recognition。
- 对照截图查看是否命中、识别框位置及工具提供的识别详情。
- 需要执行动作时,先确认当前账号、画面和操作后果;节点调试也可能产生真实点击。
截图与 ROI 获取
- 使用插件的截图功能获取模拟器当前画面。
- 在截图上框选需要识别的区域。
- 获取 ROI 坐标
[x, y, width, height],核对截图尺寸与资源使用的坐标基准。 - 写入 Pipeline 的
roi字段,并在目标画面和相似的非目标画面上复测。
取色
- 使用插件的取色功能查看目标区域颜色。
- 根据
ColorMatch使用的颜色空间设置lower和upper,不要直接将 RGB 数值当作 HSV 范围。 - 在亮度、动画或背景变化时复测,确认颜色范围没有误命中。
调试验证流程
- 修改 Pipeline 后,先处理编辑器静态诊断。
- 调试单个识别节点,确认目标命中、非目标不命中、ROI 合适。
- 在可控画面验证动作位置和效果。
- 手动运行完整任务,验证节点衔接、停止和异常分支。
方式二:资源校验脚本
scripts/check_resource.py 调用 MaaFramework 加载指定资源目录,以加载状态判断是否成功。它不是完整的静态分析器,也不是任务测试程序。
使用方法
# 在仓库根目录同步锁定的项目环境
uv sync
# 加载当前项目的基础资源包
uv run scripts/check_resource.py assets/resource/base
校验内容
- 脚本创建一个
Resource,按命令行参数顺序调用resource.post_bundle(dir).wait(),检查返回状态是否成功。 - 多个目录会连续加载到同一个
Resource,后续加载可受到前面资源的影响;这不是各目录独立、隔离的验证。要单独验证某个资源包,应单独运行一次命令。 - 任一目录加载失败,立即返回失败并以退出码
1结束;未提供目录参数也退出1。全部加载成功才输出All directories checked.。 - JSON、资源路径等问题是否在加载阶段报错,由所用 MaaFramework 版本决定。不能把脚本成功等同于所有模板、OCR 模型或
next引用都已逐项验证。 - 脚本不导入
agent的自定义动作/识别器,不检查custom_action/custom_recognition是否与 Python 注册名称匹配,也不连接控制器、启动任务或运行图像识别。注册和运行问题需在实际宿主与 Agent 配合时验证。
本地与 CI 的区别
本地 uv run 使用项目环境,pyproject.toml 固定 maafw==5.12.3,依赖由 uv.lock 管理。
当前 .github/workflows/check.yml 在 macos-latest 上执行 python -m pip install --upgrade maafw --pre,再用该 Python 运行资源检查;虽然安装了 uv,但没有通过 uv sync 使用项目锁定环境。因此 CI 可能使用不同的 MaaFramework 版本,其结果不能视为本地锁定版本或 Windows 模拟器运行结果。
方式三:MaaDebugger 独立调试
MaaDebugger 是可脱离 VSCode 使用的独立调试工具,但不在本项目 pyproject.toml 或 package.json 的依赖中。
安装与启动
按 MaaDebugger 官方仓库 的当前说明选择与资源兼容的版本、安装方式和启动命令。建议使用独立环境,不要为了安装调试工具而升级项目锁定的 maafw。
项目的 开发随笔 保留了历史安装和启动记录;其中的命令、端口参数不代表当前工具版本或项目环境一定支持。
使用
- 按所选版本说明启动工具并连接模拟器。
- 加载
assets/resource/base。 - 使用工具实际提供的节点调试、截图和日志功能定位问题。
- 涉及 Python 自定义扩展时,先确认工具是否支持所需 Agent 接入;不能因资源可加载就认为自定义动作可以执行。
方式四:手动运行验证(端到端测试)
前置条件
- 按 快速开始 准备环境;本地 Python 依赖通过
uv sync同步。 - MuMu 模拟器和星痕共鸣已启动,ADB 连接正常,游戏处于待测任务要求的起始页面。
- 已准备能加载本次修改资源的 MFAAvalonia 运行环境;涉及 Python 自定义扩展时,也要确认宿主实际启动的是本次修改的 Agent,而非旧安装目录中的副本。
- 使用允许测试的账号,明确哪些操作可能消耗道具、货币或改变游戏状态。
运行步骤
- 启动 MFAAvalonia,加载对应资源与
assets/interface.json定义的任务、选项。 - 只选择本次需要验证的任务,记录选项值和起始画面,再开始运行。
- 结合界面、框架日志和 Agent 日志观察识别、动作与流程结果。
- 修改了共享节点或自定义扩展时,补测使用它们的相关任务。
.vscode/launch.json 提供了“启动agent”调试配置,但启动 Agent 不等于启动完整任务。其连接标识必须与当前宿主会话匹配,不能把示例参数当成通用启动参数。普通端到端验收优先沿用 MFAAvalonia 的宿主启动流程。
验证要点
| 场景 | 操作 | 验收内容 |
|---|---|---|
| 正常完成 | 从约定起始画面执行任务,覆盖本次修改的选项 | 参数生效、识别和点击正确、任务到达预期结束状态 |
| 用户停止 | 在循环、等待识别和自定义动作执行期间分别点击停止 | 当前操作收尾后不再发起新一轮点击或按键;若动作按住了按键/触摸,应确认已释放,任务状态可恢复 |
| 识别失败 | 使用目标不存在或被遮挡的可控画面 | 按既定失败路径、超时或退出逻辑结束,不无限空转、不误点其他控件 |
| 弹窗或非预期页面 | 在可复现、可恢复的条件下引入弹窗或切换页面 | 按功能设计恢复或明确失败;没有处理该场景时记录限制,不能写成已自动恢复 |
| 设备或网络异常 | 在可恢复的条件下断开 ADB 或触发网络异常 | 日志能定位失败,任务不继续错误操作;恢复连接后可按规定重新启动 |
记录所用资源、框架和 UI 版本、模拟器分辨率、任务选项、实际结果以及必要的日志/截图。不能复现的维护、掉线等场景应标为未验证,不能以推测代替验收。
方式五:脚本化测试(可行性分析)
当前状态
项目目前没有正式的 pytest/unittest 测试套件、coverage gate 或 npm test。资源检查、pre-commit hook 和文档构建是现有可执行检查,不包含 Python 业务逻辑的自动化断言。
可行的脚本化测试
以下命令均在仓库根目录执行,按修改范围选择,不需要把所有命令重复运行:
| 修改内容 | 现有命令 | 检查范围 |
|---|---|---|
| Pipeline、图片或其他资源 | uv run scripts/check_resource.py assets/resource/base | MaaFramework 资源加载状态 |
| 文档、侧栏或站点配置 | 首次安装依赖执行 npm ci,然后 npm run docs:check | Docusaurus 构建及其诊断 |
| 提交前的文件规范检查 | uv run pre-commit run --all-files | 当前配置的文件筛选和 hook |
文档工具要求 Node.js >=20。npm run docs:check 和 npm run build 都执行 docusaurus build,不是两套独立测试。构建成功后,仍需在浏览器中检查受影响页面的导航、链接和显示效果。
当前 .pre-commit-config.yaml 配置了 oxipng、Prettier 和 markdownlint-cli2:
- oxipng 按配置中的
files规则筛选图片,并带有压缩、剥离元数据参数;不要把它当成图片识别正确性检查。 - Prettier 仅处理 YAML/JSON,不负责 Python、JavaScript 或 Markdown 格式检查。
- markdownlint-cli2 仅处理
docs/**和根README.md中匹配的 Markdown,带有--fix,不覆盖所有根目录 Markdown 文件。
这些 hook 可能改写文件,首次运行还可能下载工具环境。运行后需检查实际修改;--all-files 表示扩大候选文件集合,不会绕过各 hook 的文件类型和路径限制。它们不执行资源加载、Python 单元测试或模拟器任务。
不可完全脚本化的部分
以下项目不能只凭当前的资源检查或文档构建判定通过,仍需实际游戏画面和运行记录:
- 图像识别准确性:目标与相似非目标画面上的模板匹配、OCR 结果。
- 坐标点击精度:当前分辨率和 UI 状态下的实际点击效果。
- 时序和延迟:加载、动画、等待及节点切换是否符合预期。
- 停止与异常处理:循环是否响应停止,掉线、弹窗和识别失败时是否按设计退出或恢复。
建议的测试策略
- 开发时先处理编辑器静态诊断,再用插件或可选调试工具验证单个节点。
- 资源修改后执行项目资源加载检查;文档修改后执行
npm run docs:check。 - 提交前按需执行 pre-commit,查看自动修复内容,再完成受影响任务的模拟器验收。
- 发布前回归关键任务与共享节点调用方,记录通过、失败和未验证项。没有运行的场景不写“无回归”。
调试技巧
1. 日志调试
项目依赖包含 loguru。调试时同时查看框架日志和 Agent 日志,记录参数、当前节点、实际识别结果和异常上下文;日志级别与输出位置以实际运行配置为准。
不要只凭一条“任务结束”日志判断业务成功,应与预期结束画面和任务状态核对。共享日志前清除账号信息、设备标识及其他敏感内容。
2. 识别调试
保留目标画面和相似的非目标画面,记录 ROI、识别参数与实际结果。优先使用插件或调试工具已有的截图和识别详情功能。
若需要在 Python 中临时采集数据,应按当前 maafw 版本的 API 和项目现有调用方式处理截图失败、空识别结果及不同识别算法的返回字段,不假定所有结果都有 text、score 或 hit。定位结束后移除临时采集逻辑和截图文件。
3. Pipeline 调试
先缩小到失败节点和它的候选后继,核对当前画面与候选节点各自的识别条件。next 按候选顺序选择首个识别命中的节点,不是按当前节点成功/失败选择两个固定分支。
不要直接添加引用未注册动作的调试节点;资源加载检查不会替你验证 Python 注册。需要临时节点时,应复用已确认可用的动作,并在定位后移除,避免改变正常流程。
4. 通用文字识别节点
项目的 通用文字识别 节点可通过 pipeline_override 指定识别内容。以下仅是已有 CustomAction 上下文中的调用片段;context、截图 img 和 ROI 坐标需要由调用方提供,不能作为独立测试直接运行:
result = context.run_recognition(
"通用文字识别",
img,
pipeline_override={
"通用文字识别": {
"expected": "目标文字",
"roi": [x, y, w, h]
}
}
)
常见问题
Q: 识别不到目标怎么办?
- 检查 ROI 是否正确(用 VSCode 插件截图验证)
- 检查模板图片是否清晰、是否包含足够特征
- 对照目标与非目标样本调整
threshold,不要只通过降低阈值让单张截图命中 - 需要模板遮罩时,按当前 MaaFramework 版本支持的字段配置,不套用旧版本字段
- 对于 OCR,检查
expected文字是否与实际显示一致
Q: 点击位置偏移怎么办?
- 核对模拟器分辨率、截图尺寸和 Pipeline 坐标基准是否一致
- 需要相对识别结果点击时,检查动作的
target和偏移配置,避免沿用失效的固定坐标 - 检查 ROI 与实际可点击区域,并确认动画结束后的位置
Q: 任务运行中断了怎么办?
- 从框架与 Agent 日志区分用户停止、识别等待超时和业务失败
- 对照游戏画面确认是否因弹窗、页面变化或设备异常无法继续
- 检查自定义扩展是否注册、异常是否被记录,以及返回失败后是否进入预期路径
Q: 如何调试循环任务?
对于通过 next 回到自身或上游节点的循环:
- 先单独调试循环体内的识别与动作,再验证节点衔接。
- 使用可控运行时长观察重复执行,确认没有空转或误点。
- 在识别等待和自定义动作期间分别手动停止,检查是否及时结束并释放输入状态。
- 核对
rate_limit、识别等待timeout与业务退出条件。timeout不是整个任务的总时限,不能据此断言循环总会自动停止;没有自然终点的任务必须验证用户停止路径。