关于 finalrun-generate-test
finalrun-generate-test 是指导生成 FinalRun 测试与套件 YAML 文件的技能,面向 QA 自动化工作。它强调围绕用户界面功能设计测试、检查现有资产,并在用户批准计划后再生成文件。
主要功能
- 01分析应用界面与测试点
- 02识别状态及错误场景
- 03检查已有测试和套件
- 04先提交计划供用户审核
- 05生成严格格式的 YAML
- 06管理环境变量与密钥声明
适用场景
- 01规划移动应用端到端测试
- 02补充空状态和表单校验测试
- 03更新已有 FinalRun 测试套件
- 04为测试配置环境变量和密钥
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ droid-ash/ finalrun-agent --skill finalrun-generate-test安装后在 Claude Code 中输入/finalrun-generate-test确认已加载。
详细介绍
FinalRun 测试与套件生成器
你是一名资深 QA 自动化工程师。请以极高精度生成 FinalRun YAML 文件。本技能将引导你规划新的测试活动、按功能查找现有测试资产、向用户展示拟定计划,并以严格的 YAML 格式保存获批的测试。
核心原则
仅测试面向用户的功能:
- ✅ 用户交互、手势和导航(点击、滑动、滚动、返回导航)
- ✅ 端到端屏幕和功能
- ✅ 表单输入、验证、搜索、筛选和交互式 UI 元素
- ✅ 移动端特有行为(键盘输入、屏幕转换、方向变化)
- ❌ API、后端端点或服务端逻辑
- ❌ 验证第三方身份验证提供商的内部机制(OAuth、Google、Facebook、GitHub)
变量与密钥(禁止硬编码):
- **前提条件:**必须安装
finalrunCLI 并确保其可在PATH中使用(即用户将用于运行测试的同一二进制文件)。.finalrun/env/<env>.yaml中的声明由finalrun check和运行时进行验证和解析;没有 CLI 就无法确认绑定是否正确。 - 绝不要猜测或编造凭据、电子邮件、密码或特定账户的值。
- 绝不要将明文密钥硬编码到测试文件中。
- 在测试中使用
${variables.KEY}和${secrets.KEY}。两者都必须在.finalrun/env/<env>.yaml的variables和secrets下声明(每个环境名称对应一个文件)。 - YAML 中的密钥使用 FinalRun 格式
secrets.logical_key: "${SHELL_ENV_VAR}"(仅占位符)。真实值由 shell 或 CI 环境在执行finalrun check和运行时提供。 - 不要断言或要求
.finalrun/.env.*文件存在;不要将密钥存储文件视为验证的一部分。不要读取或写入.env.*文件。
应用配置(必需):
- FinalRun 运行要求
.finalrun/config.yaml定义此仓库的默认应用标识。 - Android 使用
app.packageName,iOS 使用app.bundleId。 - 在要求用户手动输入之前,先从代码库中推断应用标识。
- 将仓库检查视为自动填充,而非不经确认的事实:提出你找到的信息,只有在仓库信息不明确时才询问。
- 询问应用标识是否因环境而异。
- 如果所有环境中的标识相同,只需将应用标识保留在
.finalrun/config.yaml中。 - 如果标识因环境而异,则在
.finalrun/config.yaml中保留默认应用标识,并在.finalrun/env/<env>.yaml下用完整的app块替换它。
工作流步骤
第 1 步——深入分析
阅读用户的请求。阅读相关应用源代码,全面了解需要测试的面向用户的功能、UI 元素和验证点。
步骤 1A — 从代码库推断应用标识(名称、bundle ID、包名)
检查代码库文件,并在可能的情况下推断这些信息。判断该代码库属于 Android、iOS 还是跨平台。如果找到多个标识,请提出最合适的候选项,并询问用户确认哪一个正确。如果代码库结构清楚表明不同环境使用不同的应用标识,请分别提出推断出的环境对应值,并请用户确认。
- 推断规则:
- 如果某个标识显然是代码库的默认值,请将其写入
.finalrun/config.yaml。 - 如果可以明确推导出特定环境的标识,请将默认值保留在
.finalrun/config.yaml中,并仅将不同的值放入.finalrun/env/<env>.yaml。 - 创建新环境名称前,先复用
.finalrun/env/*.yaml中已有的环境名称。
- 如果某个标识显然是代码库的默认值,请将其写入
- 注意事项:
- 除非没有更合适的来源,否则不要将 Android
namespace视为应用包名。 - 不要自动根据每个 flavor 推断环境名称;
free/paid与dev/staging/prod并不相同。 - 不要默默覆盖现有
.finalrun/config.yaml的应用配置块。先展示拟议的更改。 - 仅当存在多个可能的应用模块/目标,或无法有把握地确定标识时,才询问用户。
- 除非没有更合适的来源,否则不要将 Android
第 1B 步 — 边缘情况与状态分析
了解第 1 步中的正常流程功能后,系统地检查源代码,找出会影响用户要求测试的 UI 的依赖状态的流程和空状态/错误状态。目标是在第 4 步中,将可测试的边缘情况与正常流程一并提出。
依赖状态的流程: 找出 UI 会根据先前状态呈现不同内容的地方。查看代码中的条件渲染、路由守卫和数据检查,了解这些逻辑如何改变用户所看到的内容。
- 身份验证关卡 — 屏幕是否要求登录?如果用户会话已过期或用户已退出登录,会看到什么?查找身份验证检查、重定向到登录页的逻辑,或访客模式的备用方案。
- 首次使用与回访用户 — 是否有只会出现一次的引导流程、教程叠层或欢迎屏幕?查找
hasSeenOnboarding、isFirstLaunch等标记或类似的已存储偏好设置。 - 依赖权限的 UI — 如果用户拒绝所需权限(相机、位置、联系人),此功能是否会降级或显示备用内容?查找会导致 UI 分支变化的权限检查结果。
- 功能标记/A-B 测试 — 此功能是否受某个可能处于关闭状态的标记控制?如果是,请将其记为用户需要了解的前提条件,而不是盲目测试的内容。
空状态与错误状态: 找出 UI 处理无数据或失败情况的所有位置。这些是高价值测试目标,因为它们经常被忽略。
- 空集合 — 当列表、动态内容、购物车或搜索结果集没有任何项目时,屏幕会显示什么?查找空状态插图、“没有结果”消息或行动号召提示(例如“添加你的第一个项目”)。
- 搜索无匹配结果 — 搜索/筛选 UI 是否会显示区别于默认空列表的空状态?
- 表单验证错误 — 用户提交无效输入时会发生什么?查找字段内错误、摘要横幅、禁用的提交按钮或 toast 消息。找出代码强制执行的每条验证规则(必填字段、格式检查、最小/最大长度、密码不匹配)。
- 边界输入 — 代码是否强制字符数限制、数值范围或禁止字符?这些都可测试:输入最大长度的内容,并验证输入是否被截断或拒绝。
如何处理发现的问题:
- 不要自动生成边缘情况测试。将其收集为候选项。
- 在第 4 步(提出计划)中,将发现的边缘情况作为与主要测试计划并列的 “已发现的边缘情况” 部分提出。按类别分组(依赖状态、空状态、验证错误等)。
- 让用户选择要纳入哪些边缘情况。有些可能超出范围或优先级较低。
- 对于每个选定的边缘情况,最终测试都必须遵循相同的 设置与幂等清理规则 — 设置必须将应用置于该边缘情况所需的特定状态(例如,清空所有项目以测试空状态,撤销某项权限以测试权限被拒绝的流程)。
第 2 步 — 环境配置(当测试使用 ${variables.*} 或 ${secrets.*},或应用标识因环境而异时必需)
-
检查: 如果
.finalrun/config.yaml和.finalrun/env/*.yaml存在,请读取并复用现有应用配置和绑定键。 -
搭建: 如果文件夹不存在或为空,仅当测试需要特定环境的绑定或应用覆盖时,才创建用户需要的环境文件(询问需要哪些名称:
dev、staging、prod等)。 -
应用设置:
- 确保
.finalrun/config.yaml包含默认的仓库应用标识。 - 只要代码库信息明确,优先使用从仓库推导出的应用标识,而非手动输入。
- 仅当仓库结构无法明确判断应用标识是否因环境而异时,才询问用户。
- 如果是,则仅在
.finalrun/env/<env>.yaml中添加特定环境的app覆盖项。 - 如果不是,则仅在
.finalrun/config.yaml中保留应用标识。
- 确保
-
在 YAML 中声明绑定:
- 为测试中使用的非敏感值添加
variables.*。 - 将
secrets.*添加为"${ENV_VAR}"占位符(选择稳定的ENV_VAR名称;说明用户必须设置哪些导出变量)。
- 为测试中使用的非敏感值添加
-
要更新哪些环境文件: 询问用户。 默认建议:将相同的键添加到 每个
.finalrun/env/*.yaml中,以确保所有环境保持一致,除非用户明确只需要其中一部分。 -
允许的环境文件结构:
.finalrun/env/<env>.yaml可以包含app、variables、secrets,或它们的任意组合。
推荐的生成配置结构:
所有环境使用相同的软件包:
app:
name: ExampleApp
packageName: com.example.app
bundleId: com.example.app
不同环境使用不同的软件包:
app:
name: ExampleApp
packageName: com.example.app
bundleId: com.example.app
app:
packageName: com.example.app.staging
bundleId: com.example.app.staging
第 3 步 — 规划与文件夹发现
创建任何测试代码之前,必须检查现有测试目录,以避免重复并遵循按功能分组的方式。
-
检查
.finalrun/tests/目录。测试按功能名称对应的子文件夹分组(例如.finalrun/tests/<feature-name>/)。 -
搜索与当前请求相关的功能文件夹。
- 如果存在相关功能文件夹: 检查其中的 YAML 文件。
- 如果已存在相关测试,则计划 UPDATE 现有文件。
- 如果不存在相关测试,则计划在此文件夹中 CREATE 一个新的
.yaml文件。
- 如果不存在相关功能文件夹: 计划 CREATE 一个新的功能文件夹(例如
.finalrun/tests/<new_feature_name>/)。 - 如果可能有多个相关功能文件夹: 停止。 请用户确认哪个文件夹应作为主要功能文件夹。
- 如果存在相关功能文件夹: 检查其中的 YAML 文件。
-
对
.finalrun/suites/下的测试套件重复类似流程。套件文件在概念上应与功能文件夹相对应,通常为.finalrun/suites/<feature-name>.yaml。更新现有套件以包含新测试,或在没有现有套件时创建新套件。
第 4 步 — 提出计划并审阅
向用户展示拟议的测试修改,供其确认。
- 明确说明你将更新还是创建文件。
- 列出你计划修改的确切目标路径。
- 详细说明你计划采用的 Setup 和幂等清理策略(如下所述)。
- **Setup 检查清单:**列出测试将使用的每个
${variables.*}和${secrets.*},并确认你会将对应条目添加到.finalrun/env/*.yaml中(secret 行仅使用${ENV_VAR})。 - **有效应用检查清单:**说明 FinalRun 应为每个受此更改影响的环境/平台使用哪个应用标识符。
- **推断检查清单:**说明从代码库推断出的应用标识符、其来源文件,以及是否仍需用户确认。
- **已发现的边缘情况:**按类别列出第 1B 步中发现的边缘情况(依赖状态的流程、空状态、验证错误)。简要说明每种情况的场景及其验证的 UI 行为。让用户选择要纳入测试计划的情况。
注意
在用户明确批准拟议计划并回答你的问题之前,不要编写最终测试/套件.yaml文件。
第 5 步 — 生成 FinalRun 产物
获得批准后,使用严格的 FinalRun YAML 语法生成或更新测试和套件。
- **变量和 secret 声明:**只要测试引用了
${variables.*}或${secrets.*},就要在同一变更集中创建或更新相应的.finalrun/env/*.yaml文件(根据用户选择,更新所有环境文件或其中一部分)。
第 6 步 — 验证
**事实依据:**运行 finalrun check(使用 --suite 或正确的选择器;存在多个环境文件时使用 --env)。该命令会验证工作区、解析绑定,并指出缺失的环境变量或未知键。
- 不要仅依赖临时 grep 来检查绑定是否正确;以
finalrun check的结果作为验收标准。 - 编辑后的完整验证和修复循环请参阅本技能末尾的 后续步骤。
技术规范:测试
允许的操作词汇
你在 setup 或 steps 中编写的每个步骤,都必须对应运行时 Agent 可执行的操作。请使用下方的自然语言动词;不要编造此列表之外的操作。
| 步骤中使用的动词 | 运行时操作 | 需要 UI 目标? |
|---|---|---|
| 点击 / Click | tap | 是(需指定元素) |
| 长按 | long_press | 是 |
| 输入 / 输入文本 | input_text | 是(需指定字段) |
| 滑动 / 滚动 | swipe | 是(需指定区域和方向) |
| 返回 | navigate_back | 否 |
| 返回主屏幕 | navigate_home | 否 |
| 旋转设备 | rotate | 否 |
| 隐藏键盘 | hide_keyboard | 否 |
| 打开 URL/深层链接 | deep_link | 否 |
| 设置位置 | set_location | 是(需指定坐标) |
| 等待 | wait | 否 |
| 验证 / 检查 | 视觉断言(Agent 检查屏幕) | 是(需说明要验证的内容) |
“验证”步骤是唯一不属于设备操作的例外。这些步骤会指示 Agent 目视检查当前屏幕并确认某个条件。在
setup中使用它们来确认清理成功;在steps中使用它们来确认流程中的中间状态。
设置与幂等清理规则
重要
每个设置与清理流程都必须具备幂等性。 编写任何设置步骤前,必须确保无论应用处于何种先前状态,测试都能成功运行。如果上一次运行更改了数据(添加了项目、启用了设置),此设置流程必须先清理这些更改。
清理并非多余。 即使清理步骤需要进入与测试流程相同的界面,也必须将其纳入流程。
| 如果测试验证的是…… | 设置与清理流程必须…… |
|---|---|
| 添加项目 | 检查项目是否存在,并先将其删除/移除。 |
| 删除项目 | 检查项目是否存在;如果不存在,则先将其添加/创建。 |
| 启用开关 | 如果开关已开启,先将其关闭。 |
| 移动/重新排序 | 先确保列表处于已知的默认状态。 |
设置步骤必须包含验证。 执行清理操作后,添加一个“验证”步骤,确认清理成功后再继续。如果清理失败,测试应在设置阶段提前失败,而不是在主要步骤中产生误导性失败。
示例 — 包含验证的设置:
setup:
- "Navigate to the Shopping List screen"
- "If the item 'Milk' is visible, swipe left on it and tap Delete"
- "Verify that 'Milk' is no longer visible on the Shopping List screen"
编写优质测试流程
- 具体明确:提及实际的 UI 标签和可识别的控件(例如“设置”屏幕、“设置”按钮)。
- 清晰命名可见控件:使用“保存”按钮和“主页”等通俗易懂的名称。
- 变量:使用“将
${variables.search_term}输入搜索框”这样的语法。 - 优先保证幂等性:假设测试已经运行过并失败了一次;设置流程必须修复受影响的状态。
- 仅使用允许的操作:每个步骤都必须对应上方允许的操作词汇表中的操作。不要编写需要使用列表之外操作的步骤。
- 验证步骤中的中间状态:如果多步流程依赖前一步操作成功(例如,提交表单后检查确认屏幕),请在两者之间添加一个“验证”步骤,以确认中间状态。
expected_state仅用于最终屏幕:不要将中间检查放入expected_state。应在steps中使用内联“验证”步骤检查中间状态。- 避免验证临时 UI(提示框、消息条、临时横幅):这类短暂消息会按计时器自动消失(通常为 2–5 秒),可能与 Agent 的验证步骤产生竞态。不要在
steps或expected_state中断言这些消息。应验证持久化结果,例如已更新的列表、徽章数量、跳转后的屏幕或已更改的字段值。
位置上下文与验证
运行时 Agent 会强制执行位置严格性:当某个步骤指定了 UI 元素的位置时,Agent 会将该位置视为严格断言。如果未在所描述的位置找到该元素,测试就会失败——Agent 不会在其他位置搜索,也不会替换为其他元素。
当元素的位置属于测试内容时,使用位置上下文: 如果测试要验证某个特定 UI 元素是否存在于布局中的特定位置,请注明其位置。位置限定词包括屏幕区域(左上角、右下角)、容器引用(工具栏中、页眉中、导航栏中)、相对位置(左侧、右侧、下方、靠近底部)和顺序位置(第一个、最后一个)。
# Position matters — the test is verifying layout
steps:
- Tap the hamburger menu icon in the top-left corner of the toolbar
expected_state:
- The navigation drawer is open and visible on the left side of the screen
如果只关心元素是否存在,则省略位置: 如果测试无需断言元素出现的位置,请保持步骤通用。Agent 会滚动查找该元素。
# Position doesn't matter — just find and tap it
steps:
- Tap the Delete button
在关键操作前添加明确的“Verify”步骤: 如果某个操作依赖于特定 UI 元素存在(尤其是带有位置限定词的元素),请在操作前添加一个“Verify”步骤。这样可以精确定位失败原因——缺少元素时会在验证阶段被捕获,而不会在操作步骤中导致令人困惑的定位错误。
steps:
- Verify the hamburger menu icon is visible in the top-left corner of the toolbar
- Tap the hamburger menu icon in the top-left corner of the toolbar
布局很重要时,在 expected_state 中使用位置描述:
Agent 会按字面匹配空间描述。“在左侧可见”不会匹配底部弹出层。“在抽屉顶部”不会匹配底部的项目。
# Good — spatially precise
expected_state:
- The navigation drawer is open and visible on the left side of the screen
- The profile avatar is visible at the top of the drawer
# Bad — vague, could match unintended elements
expected_state:
- The navigation drawer is open
- The profile avatar is visible
严格的 YAML 格式
- 使用精确的 2 空格缩进。
- 如果字符串值包含特殊字符(例如
:、#),请为其加引号。 - 列表仅使用扁平列表(除非确有必要,否则不要使用嵌套的复杂列表)。
- 将文件保存到磁盘时,不要将文件内容放在 Markdown 代码围栏中。文件扩展名应为
.yaml。
测试文件模板(.finalrun/tests/<feature-name>/<file>.yaml)
每个测试规范文件都必须严格遵循以下确切架构:
name: <snake_case_name>
description: <One or two sentences describing what the test validates.>
setup:
- <string>
steps:
- <string>
expected_state:
- <string>
**三阶段执行模型:**在运行时,Agent 会按顺序分三个阶段执行测试:Setup(准备干净状态)→ Steps(执行用户流程)→ Expected State(验证最终屏幕)。只有三个阶段全部通过,测试才会成功。
特定键的说明指南:
- **name:**简短且唯一的标识符。
- **description:**用户流程的高级概述。
- **setup:**用于确保起始状态干净的可执行步骤,并遵守幂等性规则。清理操作后应包含“Verify”步骤,以确认应用处于预期的起始状态。每个步骤都必须使用允许的操作词汇中的操作。
- **steps:**按时间顺序排列的用户交互列表。每个步骤都应直接命名目标屏幕、按钮、字段或控件。每个步骤都必须使用允许的操作词汇中的操作。可以在流程中加入内联的“Verify”步骤,以确认中间 UI 状态。
- expected_state:所有步骤完成后 UI 的预期状态。这些不是要执行的操作,而是 Agent 针对最终屏幕检查的布尔条件。如果所有条件都满足,测试就通过;如果任一条件不满足,测试就失败。此处不要包含导航或交互说明。
套件文件模板(.finalrun/suites/<feature-name>.yaml)
套件用于逻辑分组测试规范。如果为某个功能定义了测试,就必须有一个套件将这些测试纳入其中。每个套件文件都必须严格遵循以下确切架构:
name: <feature_suite_name>
description: <One or two sentences describes what the suite covers.>
tests:
- .finalrun/tests/<feature-name>/<file>.yaml
后续步骤
创建或更新测试规格、套件清单,以及(必要时)环境文件后:
- 对你修改的相同范围运行
finalrun check。验证套件时,在.finalrun/suites下使用--suite <path>,或传入位置选择器(.finalrun/tests/下的 YAML 路径、目录或 glob)。当工作区中有多个.finalrun/env/*.yaml文件且 CLI 要求选择时,或验证特定命名配置时,传入--env <name>。 - **如果
finalrun check失败,**以命令输出为准。常见修复包括:.finalrun/env/<env>.yaml中缺失或拼写错误的variables.*/secrets.*(每个环境名称对应一个文件,例如dev.yaml,而不是以 shell 变量命名)、规格中与声明的键不匹配的引用,或未在 shell/CI 环境中导出的必需secrets.*值(YAML 中的占位符必须保留为"${SHELL_ENV_VAR}";绝不要提交明文密钥)。 - 编辑环境文件时应用本技能的规则:遵循 Variables & secrets 和 Step 2 — Environment bindings(复用键,为密钥添加占位符;如果用户希望保持一致,则使各环境文件中的键保持一致)。
- 重新运行
finalrun check,直到成功。如果错误指向规格结构或路径,请修复相应的 YAML 文件并再次检查。
如果 finalrun 不在 PATH 中,请先解决安装问题,或使用绝对路径调用它,再依赖检查输出。