Test Plan Writer

SKILL开发
开发 未标注权限 许可证不明确
安装这个技能

基于 PRD 和代码变更分析,生成标准化测试方案(test_plan.md)。职责包括:设计测试场景、定义数据筛选条件、评估风险等级、决定所需流水线阶段。

一句话选型结论

按资料字段整理

Test Plan Writer是开发类的 Agent Skill,安装方式未标注,权限级别未标注,许可证不明确,有可直接复制的安装命令。技能本质是给模型读的说明书,效果取决于模型与客户端;装完先用一个小任务验证,再放进正式流程。

分类开发 安装方式未标注 权限级别未标注权限 许可证许可证不明确
累计安装 未标注 本周 未标注
GitHub 星标 未标注 仓库 未标注
下载量 未标注 技能市场下载数
权限级别 未标注权限 安装前请确认风险范围
许可证 许可证不明确 未说明

安装

未标注
在支持 Skills 的客户端里执行,装完问一句「你有哪些技能」验证
skillhub install user_3ddd765c/test-plan-writer
  1. 1
    确认客户端支持

    确认你的客户端支持 Skills(Claude、Codex、Cursor 等),并升级到较新的版本。

  2. 2
    拿到技能文件

    执行上面的命令安装;也可以把仓库里的 SKILL.md 手动放进客户端的 skills 目录。

  3. 3
    刷新技能列表

    重新打开客户端,或刷新技能列表,让新放进来的技能被加载。

  4. 4
    验证是否生效

    问一句「你有哪些技能」,确认列表里出现它,再拿一个小任务试跑。

技能档案

开发
字段来自技能仓库与公开索引,中文说明由本站标注
作者 / 维护方user_3ddd765c仓库 未标注 · 版本 未标注
宿主客户端未标注技能可被这些客户端加载
安装方式未标注安装包 community
权限级别未标注权限安装前请确认风险范围
许可证未说明许可证不明确,商用前请自行确认条款
仓库可用性available技能仓库当前是否可访问
最近核验未标注上游最后核验时间 · 数据更新 1791624143
正文体量35.7 KBSKILL.md 原文大小,越大说明说明书写得越细

典型使用场景

3 类
按分类整理的常见用法,具体以 SKILL.md 为准
写代码与改 bug

按需求补代码、定位并修掉报错。

读仓库与生成改动

让模型读懂项目结构,再给出可落地的改动。

跑测试与排查故障

按现象排查问题,补测试用例并复跑。

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 有可直接复制的安装命令,不用自己翻文档找入口。

先想清楚的地方

  • 没有标注权限级别,实际能做什么要装好后确认。
  • 许可证不明确,商用或二次分发前先到仓库确认条款。
  • 没有做站内核验,内容以作者仓库为准。
  • 技能只是说明书,实际效果取决于模型与客户端,装完先用小任务试一遍。

更适合

  • 需要在开发场景里给模型补一套做法的人。
  • 愿意先读一遍 SKILL.md、确认它会让模型做什么的人。

不太适合

  • 对许可证要求很严、必须明确可商用的人。
  • 只想装完就自动变强、不打算看说明书的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
技能权限级别安装方式累计安装宿主客户端安装命令
Test Plan Writer当前 未标注权限 未标注 未标注 未标注 有
技能审查员 浏览器控制 ClawHub 市场 877.9 万 OpenClaw 有
Vercel React 最佳实践 浏览器控制 GitHub 仓库 849.1 万 Codex、Claude、Cursor 有
GitHub 代码协作 联网访问 ClawHub 市场 763.3 万 OpenClaw 有
网页设计指南 联网访问 GitHub 仓库 668.6 万 Codex、Claude、Cursor 有
本体论 只读 ClawHub 市场 663.7 万 OpenClaw 有

SKILL.md 全文

35.7 KB
模型实际读到的说明书原文,来自技能仓库

测试方案生成器

角色定位

本 Skill 是方案设计层,专注测试方案生成,不执行具体测试。

职责:
1. 分析 PRD 需求与代码变更范围
2. 设计可观测协议字段级别的测试场景
3. 定义数据筛选条件(供下游 search-data 使用)
4. 评估风险等级,决定 required_phases
5. 生成标准化 test_plan.md


输入参数

参数 必填 说明
feature ✅ 功能名,用于目录命名和方案标识
designDoc ✅ map-spec 设计文档路径(.claude/workflow/<slug>/design.md)
sourceFiles map-spec 传入的 source_files.txt 文件路径(.claude/workflow/<slug>/source_files.txt)。内容为纯文本,每行一个变更文件路径。仅用于辅助了解改动范围,不用于需求分析

执行步骤

⚠️ 前置强制检查(阻塞项 vs 警告项)

在生成测试方案前,必须完成以下检查。检查项分为两类:

类型 含义 未通过处理
🔴 阻塞项 必须修复,禁止继续 返回对应步骤修正
🟡 警告项 允许标注后通过,但需在输出中显性标注 记录到自检清单

检查清单 A:代码 diff 分析(🟡 警告项)

检查项 操作 通过标准 未通过处理
读取 sourceFiles read_file <sourceFiles> 获取索引文件,解析每行得到代码文件路径列表 索引文件已读取且至少包含一个有效路径 标注 [警告: sourceFiles 为空],继续
读取代码文件 对解析出的每个路径执行 read_file <路径> 关键文件内容已读取 标注 [待确认: 需开发确认],继续
提取日志关键字 grep_code regex="LOG.*<函数名>" path="<代码文件路径>"(对列表中各文件分别搜索) 找到日志语句 标注 [待确认: 需开发确认],继续
提取 Apollo Key grep_code regex="GetConfig|apollo" path="<代码文件路径>"(对列表中各文件分别搜索) 找到配置读取 标注 [待确认: 需开发确认],继续
确认改动分支 grep_code regex="if.*event_type.*5" path="<代码文件路径>"(对列表中各文件分别搜索) 找到条件分支 标注 [警告: 未找到相关分支],继续

> 为什么不阻塞? sourceFiles 可能为空(map-spec 未传入),或代码变更未提交到 git。允许降级为"待确认"标注,但必须在输出中显性记录。


检查清单 B:字段存在性确认(🔴 阻塞项)

检查项 操作 通过标准 未通过处理
Thrift 搜索 grep_code regex="<字段名>" path="src/navi-guide/src/proto/thrift" 找到字段定义 阻塞:禁止虚构字段
Proto 搜索 grep_code regex="<字段名>" path="src/navi-guide/src/proto/protobuf" 找到字段定义 阻塞:禁止虚构字段
建立字段来源表 记录字段所属消息和行号 每个字段都有来源 阻塞:必须补充来源

> 为什么阻塞? 虚构协议字段会导致测试方案完全不可执行,下游 search-data 和 diff 都会失败。这是底线。


检查清单 C:预期结果量化检查(🔴 阻塞项)

检查项 检查内容 通过标准 未通过处理
数值量化 包含具体数值或范围 如"数量 >= 1"而非"有效" 阻塞:返回修正
字段结构 包含具体的字段名 如"forkPoint 非空" 阻塞:返回修正
识别方法 内部状态的识别规则 如"通过 multiRoadsForkPoints 非空识别" 阻塞:返回修正

禁止使用的模糊词:正常、有效、正确、成功、合理、优化、提升、改善、包含有效信息、解析成功

例外处理:若确实无法量化(如用户体验类优化),在 说明 中写明量化困难原因和替代验证方式 → 降为 🟡 警告项,允许通过。


Step 1: 读取设计文档

  1. 读取 designDoc
    - 读取 map-spec 生成的设计文档
    - 提取:功能描述、生效场景、改动点、约束条件、涉及的协议字段

  2. 提取测试设计要素
    - 从 designDoc 中直接提取测试所需信息,包括:

    • trigger_condition:生效场景、约束条件
    • expected_behavior:功能描述中的预期输出
    • affected_fields:涉及的协议字段

Step 2: 提取关键信息

从 designDoc(map-spec 设计文档)中提取:
- 功能描述与生效场景
- 涉及的协议字段(如 ttsContent、voiceType、eventType)
- 触发条件(如 scene_type == F_FORK && distance <= 150m)
- 功能开关控制:
- 开关类型(灰度 / AB实验 / Apollo配置 / 无)
- Apollo Key、默认值
- 若是灰度:白名单内容
- 若是 AB实验:实验组/对照组白名单、实验ID
- 若是 Apollo配置:本地配置是否生效
- 约束条件(如"不影响普通十字路口")
- 改动点(文件、函数、插入位置)

可查询信息源(AI 在生成方案时可主动查询):

信息源 查询方式 用途
知识库(LLM-Wiki) 调用 http://10.190.56.84:8080/search 语义检索与 feature / sourceFiles / 字段名 / 服务相关关键词 了解同类功能的历史测试方案、已知问题、协议字段含义、边界条件、服务部署配置、测试策略决策、数据筛选经验、diff 分析规则、回归测试经验
历史用例 检索 src/navi_guide_tools/case/ 下同类功能的测试用例 复用或参考历史场景的 trigger_condition、数据筛选条件
协议定义 读取 src/navi-guide/src/proto/ 下的 .thrift / .proto 文件 提取协议中实际存在的字段名、字段类型、嵌套结构,作为黑盒测试的唯一输入输出依据
Apollo 配置 检索相关配置项或白名单定义 确认开关类型、白名单内容、AB 实验分组规则
代码变更 读取 sourceFiles 中的具体代码 diff 确认改动点、新增字段、条件分支逻辑

> designDoc 是主要信息来源,已包含足够的需求描述和变更范围。当 designDoc 信息不足以准确描述预期输入输出(如字段取值范围、协议格式、历史兼容性约束)时,必须主动查询上述信息源补充,确保测试方案准确。
>
> 黑盒测试约束:本 Skill 生成的测试方案用于黑盒测试,所有 trigger_condition(输入条件)和 expected_behavior(预期输出)中的字段必须是协议中实际存在的字段。禁止构造协议中不存在的字段或假设未定义的嵌套结构。若对字段存在性有疑问,必须查询协议定义文件确认。

Step 2.5: 字段存在性确认(阻塞项)

在生成任何测试场景之前,必须完成以下确认:

1. 字段存在性确认顺序(知识库 → Proto 真相源)

采用两级确认机制,平衡效率与准确性:

Step 1: 查询 LLM-Wiki 知识库(快速索引)
    └─ 字段在检索结果中?→ 是 → 直接使用,跳过 proto 搜索
    └─ 字段不在检索结果中?→ 否 → 进入 Step 2

Step 2: 搜索 Proto 文件(唯一真相源)
    └─ 字段在 proto 中?→ 是 → 新字段,记录并标注 [新增字段: 待 LLM-Wiki 同步]
    └─ 字段不在 proto 中?→ 否 → 进入 Step 3

Step 3: 代码 diff 辅助校验
    └─ 在 diff 中找到?→ 是 → 可能是内部变量,禁止用于测试
    └─ 在 diff 中也找不到?→ 否 → 标注 [待确认: 需开发确认]

LLM-Wiki 知识库检索

服务地址:http://10.190.56.84:8080
Collection:navi-guide-qa-knowledge(需预先创建并上传知识库文档)

检索方式:

POST http://10.190.56.84:8080/search
Content-Type: application/json

{
  "collection": "navi-guide-qa-knowledge",
  "query": "<feature 关键词 或 字段名>",
  "limit": 5
}

检索时机:
- Step 1 字段存在性确认时,用字段名作为 query 快速检索
- 设计测试场景前,用 feature 关键词检索历史测试方案和已知问题
- 遇到边界条件不确定时,检索相关规则和经验
- 确定测试策略时:检索同类功能的 required_phases 决策依据、风险等级评估标准
- 定义数据筛选条件时:检索历史筛选方案(diff / script / reuse)的选择依据和 filter_config 模板
- 配置功能开关时:检索历史 Apollo Key 命名规范、灰度开关配置模式、AB 实验分组规则
- 定义预期差异时:检索历史 diff 预期差异定义格式、unexpected_diff 判定规则
- 设计业务场景时:检索业务规则、播报逻辑、轮次定义、场景触发条件等业务知识(如"播报轮次"、"路口类型"、"距离阈值"等)

> 检索结果中的 heading 和 text 可用于拼接 RAG 上下文,辅助测试方案设计。
> LLM-Wiki 检索结果不能作为字段存在性的最终依据,最终确认仍需搜索 proto 文件。

协议文件(唯一真相源):

导航服务采用 Thrift 定义接口 + Protobuf 定义响应数据结构,需区分搜索:

字段类型 协议文件 搜索目标
请求字段(如 event_type、route_type) .thrift 文件 navi_guide_service.thrift 中的 NaviGuideRequest
响应字段(如 eventType、forkPoint) .proto 文件 RouteGuidanceInfo、RouteGuidanceInfos 等消息

唯一搜索范围:src/navi-guide/src/proto/

该目录下包含所有 Thrift 接口定义和 Protobuf 数据结构定义,不局限于 navi_guide_service.thrift 或 navi_guide_service_apply.proto:

  • Thrift:src/navi-guide/src/proto/thrift/*.thrift(13 个文件,含接口、请求/响应结构体)
  • Proto:src/navi-guide/src/proto/protobuf/*.proto(8 个文件,含响应数据结构、路线特征、放大图等)

> 其他路径(如 src/ng_diff_new/、src/navi_guide_tools/ 下的 proto)不得作为字段存在性确认的依据。

搜索策略:
- 先用 grep_code 在 src/navi-guide/src/proto/ 下全局搜索字段名
- 若命中,读取具体文件确认字段所属消息和类型
- 若未命中,再用 search_file 扫描项目内其他 .thrift / .proto 作为兜底

2. 区分请求消息与响应消息

导航服务的协议结构特点:
- 响应消息:通常为 RouteGuidanceInfo(单路径诱导信息)或 RouteGuidanceInfos(多路径诱导信息),包含 forkPoint、multiRoadsForkPoints、eventType、ttsContent 等字段
- 请求字段:请求参数(如 event_type)通常不在单独的 "Request" 消息中定义,而是通过以下方式确认:
- 响应中 eventType 字段的注释为"请求时的event_type",说明它是从请求透传的参数
- 查阅 designDoc 中的请求参数说明
- 查阅历史用例中的请求构造代码

3. 搜索字段的具体操作

对候选字段执行以下验证,根据字段类型选择搜索目标:

A. 请求字段(trigger_condition 中使用)→ 搜索 Thrift:

# 操作 1:在 thrift 目录下全局搜索字段名(精确匹配,区分大小写)
grep_code regex="字段名\s*:" path="src/navi-guide/src/proto/thrift"

# 操作 2:查看命中的文件,确认字段所属结构体
grep_code regex="struct\s+\w+\s*\{" path="<命中文件>" -A 100

B. 响应字段(expected_behavior / affected_fields 中使用)→ 搜索 Proto:

# 操作 1:在 proto 目录下全局搜索字段名(精确匹配,区分大小写)
grep_code regex="字段名\s*=" path="src/navi-guide/src/proto/protobuf"

# 操作 2:查看命中的文件,确认字段所属消息
grep_code regex="message\s+\w+\s*\{" path="<命中文件>" -A 200

# 操作 3:若无精确匹配,尝试模糊搜索
grep_code regex="字段名" path="src/navi-guide/src/proto/protobuf" -i

4. 建立字段来源表

每确认一个字段,记录到来源表:

字段名 来源(请求/响应) proto 中的消息 确认方式
eventType 响应(请求透传) RouteGuidanceInfo 精确匹配
multiRoadsForkPoints 响应 RouteGuidanceInfo 精确匹配

5. 代码 diff 辅助校验(解决字段名/关键字精确性)

> 此步骤利用代码变更内容辅助校验 designDoc 中提到的字段名、日志关键字、Apollo Key 是否与代码实现一致。不是需求融合,仅为命名精确性校验。

当 designDoc 中提到的以下信息需要精确确认时,读取代码 diff 辅助验证:

获取 diff 的方式(按优先级):
1. sourceFiles 参数中的变更文件列表 → 直接读取这些文件的关键代码段
2. 执行 git diff HEAD → 获取完整代码变更
3. 检查 workflowDir/diff-report.md → map-spec code-review 阶段已生成的 diff 报告

diff 辅助校验的应用场景:

场景 操作 示例
designDoc 写 event_type,不确定 proto 中是 event_type 还是 eventType 在 diff 中搜索 event_type 和 eventType,看代码中实际使用的字段名 diff 中出现 eventType = request->event_type → 确认 proto 中是 eventType
designDoc 提到"日志打印 SetmultiRoadsForkPoints" 在 diff 中搜索 LOG 或 printf 语句,确认日志关键字 exact match diff 中出现 LOG(INFO) << "SetmultiRoadsForkPoints event_type=" → 确认关键字
designDoc 提到"灰度开关 fix_eventtype5" 在 diff 中搜索 apollo 或 GetConfig,确认 Apollo Key 完整名称 diff 中出现 GetConfig("fix_eventtype5_parseforkpoint_gray_switch") → 确认 Key
designDoc 提到新增字段 fork_points 在 diff 中搜索 fork_points,若代码中只有 forkPoint 和 multiRoadsForkPoints → 禁止虚构 fork_points

校验规则:
- 若 designDoc 中的字段名/关键字与 diff 中的代码实现不一致,以代码实现为准
- 若 designDoc 中未提及但 diff 中发现新增字段/开关,在测试方案中标注为新增,并纳入字段来源表
- 若 diff 中也找不到对应字段,标注 [待确认: 需开发确认]

6. 字段不在现有来源表中的处理(新字段发现流程)

若搜索到的字段不在当前字段来源表中,说明可能是新引入的字段,执行:

  1. 确认是否为本次需求新增字段:
    - 结合 sourceFiles 和 diff 内容,确认该字段是否在本次变更中新增
    - 若是新增字段 → 进入新字段确认流程
    - 若是已有字段但来源表遗漏 → 补充到来源表

  2. 新字段确认流程:
    Step A: 在 .proto 中定位字段所属消息(请求/响应) Step B: 确认字段类型(optional/required/repeated) Step C: 记录到字段来源表 Step D: 同步到 LLM-Wiki(见下方「新字段知识库同步」)

新字段知识库同步

当 Step 2 发现新字段时,直接通过 /index 同步到 LLM-Wiki:

POST http://10.190.56.84:8080/index
Content-Type: application/json

{
  "collection": "navi-guide-qa-knowledge",
  "docs": [
    {
      "id": "new-field-<feature>-<field_name>",
      "text": "字段: <field_name>\n类型: <type>\n所属消息: <Message>\n来源: <proto/thrift>\n说明: <简要说明>\n引入功能: <feature>"
    }
  ]
}

> 如批量发现多个新字段,合并为一个 docs 数组一次性 /index 注入。

  1. 临时处理:若来不及同步 LLM-Wiki,在字段来源表中标注 [新增字段: 待 LLM-Wiki 同步],但不影响测试方案生成

7. 标记不确定项:若 PRD 或 designDoc 中提到的概念无法映射到协议字段(如"版本切换"、"已走过的 link"),禁止直接虚构字段名,应:
- 优先寻找协议中可间接表征该状态的字段
- 若找不到,在 trigger_condition 中使用最相关的真实字段(如 eventType == 5),并在说明中备注"版本切换状态通过响应差异反推"
- 绝不能使用 C++ 内部变量名(如 route_has_version_switch、has_traveled_links)作为测试依据

8. 字段命名规范:严格使用 proto 文件中的字段名(区分大小写,如 eventType 而非 event_type)

Step 3: 设计测试场景

📋 场景细分方法论

规则 1:触发条件相同的场景处理

当多个场景的 trigger_condition 完全相同(如都是 event_type == 5),必须采用以下方式之一:

方式 A:合并场景(统计方式)(推荐)

### S001: event_type=5 场景(合并)

- **触发条件**: `event_type == 5`
- **预期分布**:
  - 版本切换场景(约 30%):`multiRoadsForkPoints` 有差异(CHANGED)
  - 无版本切换场景(约 70%):`multiRoadsForkPoints` 无差异(UNCHANGED)
- **识别方法**: 通过响应中 `multiRoadsForkPoints` 非空识别版本切换

方式 B:区分场景(明确识别方法)

### S001: event_type=5 且发生版本切换

- **触发条件**: `event_type == 5` **且满足以下之一**:
  - 响应中 `map_version` 与请求不一致
  - 响应中 `multiRoadsForkPoints` 非空(新逻辑生效后)
- **预期行为**: `multiRoadsForkPoints` 包含分歧点(数量 >= 1)

### S002: event_type=5 且无版本切换

- **触发条件**: `event_type == 5` **且**:
  - 响应中 `map_version` 与请求一致
- **预期行为**: `multiRoadsForkPoints` 与基线一致(UNCHANGED)

> 强制要求:若采用方式 B,必须给出明确的识别字段或方法,禁止仅标注"通过响应差异反推"而不说明具体方法。

规则 2:灰度开关场景完整覆盖

若需求提到灰度开关,必须包含以下场景:

场景 触发条件 预期差异 优先级
灰度关闭 event_type == 5(灰度开关关闭) UNCHANGED(与基线一致) P0
灰度开启-生效 event_type == 5(灰度开关开启,命中白名单) CHANGED(新逻辑生效) P0
灰度开启-未生效 event_type == 5(灰度开关开启,未命中白名单) UNCHANGED(走老逻辑) P0

规则 3:边界场景系统设计

必须覆盖的边界维度(根据业务逻辑选择至少 2 个维度,每个维度至少 2 个边界点):

维度 边界点 示例场景
时间/进度边界 刚触发、触发后一段时间、长期 刚版本切换、切换后 10km、切换后到达终点
空间边界 起点、中途、终点 起点 0km、中途 50%、终点前 100m
数量边界 0、1、多个 无分歧点、1 个分歧点、多个分歧点
状态边界 正常、异常、极限 正常版本切换、切换失败、多次切换

基于协议中实际存在的可观测字段设计测试场景,每个场景必须包含:

字段 说明 字段来源限制
scenario_id 唯一标识,如 S001 -
scenario_name 场景名称,简明描述测试意图 -
trigger_condition 触发条件(协议字段 + 阈值) 只能使用请求协议中的字段
expected_behavior 预期行为(具体字段值变化) 只能使用响应协议中的字段
affected_fields 受影响的可观测字段列表 只能使用响应协议中的字段
test_type diff / functional / boundary -
验证方式 协议字段 / 日志 / 协议+日志 若选日志或协议+日志,日志关键字必须来自源码确认
priority P0 / P1 / P2 -

字段使用规则:
- trigger_condition 中的字段必须是请求消息(Request)中实际存在的字段
- expected_behavior 和 affected_fields 中的字段必须是响应消息(Response)中实际存在的字段
- 禁止将 C++ 内部变量、临时计算量、未序列化的内存对象作为测试依据
- 若需求描述中的概念无法直接映射到协议字段,应使用最接近的真实字段,并在场景说明中解释映射关系

示例场景:

### S001: F 路口提前播报
- **触发条件**: `scene_type == F_FORK && distance_to_fork <= 150m`
- **预期行为**: `ttsContent` 包含 "前方路口",提前 50m 播报
- **受影响字段**: `ttsContent`, `voiceType`
- **测试类型**: diff
- **优先级**: P0

Step 4: 定义数据筛选条件

为每个 diff 类型场景定义数据筛选条件:

条件维度 示例
scene_type F_FORK, T_JUNCTION
distance_range 100m ~ 200m
version >= 490
city_list 北京、上海、深圳
time_range 高峰时段覆盖

筛选条件字段限制:
- 筛选条件只能使用请求协议中实际存在的字段
- 禁止用响应字段、C++ 内部变量或 AI 推导的抽象概念作为筛选维度
- 若需求涉及无法直接筛选的内部状态(如"版本切换"、"已走过的 link"),应:
1. 先用请求中可筛选的字段缩小范围(如 eventType == 5)
2. 再通过 diff 输出的响应差异来识别目标场景
3. 在 说明 列中标注"内部状态通过响应差异反推,非直接筛选"

生成 data_filter_conditions 字段,供 search-data-script 使用。

Step 5: 评估风险等级、测试策略与 required_phases

根据以下因素评估:

因素 高风险表现
改动范围 核心算法、多模块联动
影响面 全量用户、全场景
字段类型 语音播报、安全相关事件
历史稳定性 同类改动曾引发线上问题

风险等级与 required_phases 映射:

风险等级 说明 required_phases
low 纯配置/文案变更,影响面极小 [1, 2, 3, 4]
medium 单一场景优化,影响面可控 [1, 2, 3, 4, 5, 6]
high 核心算法变更,多场景联动 [1, 2, 3, 4, 5, 6]

> Phase 6(汇总报告)为必须执行阶段,用于汇总各 Phase 产物生成最终报告。

测试策略建议(写入 test_plan.md "测试策略"章节):

变更类型 Diff 功能 Case 回归 说明
纯配置/文案调整 ✅ 必须 ❌ Case 生成验证配置生效
新功能/新场景 ✅ 必须 ✅
算法优化 ✅ 必须 ✅ diff 覆盖核心差异,Case 验证边界
逻辑修复/Bugfix ✅ 必须 ✅ Case 验证边界场景
接口变更 ✅ 必须 ✅

> 功能 Case 为必须执行,用于验证边界场景和补充 diff 无法覆盖的功能点。压测暂不执行。

> 逻辑修复特殊说明:若修复的是特定场景下的异常处理逻辑(如本例的 event-type=5 版本切换),功能 Case 用于验证边界场景(部分走过、全走过),压测通常不需要。需在"判断依据"中明确说明为何选择该策略。

AB 实验特殊策略:
- Diff 需跑两组:实验组(基线 vs 实验组)+ 对照组(基线 vs 对照组)
- 实验组预期:有差异(符合 test_plan 预期)
- 对照组预期:无差异(对照组应与基线一致)
- 对照组白名单:对照组可能使用独立白名单(driver_id 非空),也可能与非白名单共用默认逻辑(driver_id=""),视实验设计而定
- 若对照组出现差异 → 实验分流逻辑有问题,需标记为 bug

Step 6: 生成 test_plan.md

输出路径:<CASE_DIR>/<feature>/test_plan.md

按 test-plan-template-v2.md 模板格式生成,确保包含以下必填字段:
- feature:功能名
- 测试执行方式:列出 Jenkins MCP 调度的流水线(diff 流水线 / 回归流水线 / 压测流水线),标注是否使用
- test_scenarios:测试场景列表(每个场景含 scenario_id / trigger_condition / expected_behavior / affected_fields / test_type / 验证方式 / priority)
- 验证方式:协议字段(仅 diff 验证) / 日志(仅日志验证) / 协议+日志(两者结合)
- data_filter_conditions:数据筛选条件(供 search-data 使用)
- 功能开关控制:开关类型、白名单、实验组等信息
- 测试策略:Diff / 功能 Case / 回归 / 压测 的是否需要执行
- experiment_config:实验/灰度配置(决定 diff 执行次数和分组)
json { "type": "ab_test", "groups": [ {"name": "control", "driver_id": "202606101119", "desc": "对照组(白名单A)"}, {"name": "treatment", "driver_id": "580548822047701", "desc": "实验组(白名单B)"} ] }
- type:none(无实验)/ ab_test / grayscale
- groups:diff 分组列表,每组含 name、driver_id、desc
- driver_id:该组的白名单 ID。空字符串表示非白名单(走默认逻辑),非空字符串表示使用该白名单
- 对照组可能有自己的白名单(如对照组白名单A),也可能不设白名单(空字符串,与非白名单共用默认逻辑)
- 由功能开关控制信息自动推导:若开关类型为 AB实验/灰度,则 type 对应设置,groups 按对照组/实验组或白名单/非白名单拆分
- diff_config:Diff 执行配置与预期结果(输入不可预期,但输出必须可预期)
- 对比配置:基线/目标服务地址(对比字段、忽略字段、请求数据来源等由 ng_diff_new 内部实现决定,测试方案仅指定 host)
- 预期差异结果(Expected Diff):每个场景下哪些字段、基线值→目标值、变化方向(CHANGED/ADDED/REMOVED/UNCHANGED)。注意:diff 输入为线上真实流量,无法预先控制哪些请求会被打到,上表定义的是"如果某个请求的响应中该字段出现差异,则差异应符合上述定义"
- 分组预期差异:按 experiment_config.groups 中的 name 分组定义预期差异,格式如下:
markdown | 分组 | 场景ID | 字段 | 基线值 | 目标值 | 变化方向 | |------|--------|------|--------|--------|----------| | treatment | S001 | ttsContent | - | 包含"前方路口" | CHANGED | | treatment | S001 | multiRoadsForkPoints | 空 | 数量>=1 | ADDED | | control | S001 | ttsContent | - | - | UNCHANGED | | control | S001 | multiRoadsForkPoints | - | - | UNCHANGED |
- 实验组/白名单组:按正常场景预期填写(CHANGED / ADDED / REMOVED)
- 对照组/非白名单组:全部为 UNCHANGED,与基线一致。若对照组出现任何差异 → 实验分流逻辑有 bug(对照组无论是否有独立白名单,都应与基线一致)
- 非预期差异判定规则:哪些情况属于 unexpected_diff,供 Phase 2 diff-executor 使用
- 日志验证(如适用):哪些场景需结合日志验证、日志关键字/指标、预期结果
- required_phases:需要执行的 Phase 列表
- risk_level:风险等级(low/medium/high)

生成过程中的强制校验:
每生成一个场景,立即执行:
1. 字段来源校验:trigger_condition 中的字段是否都在请求 proto 中?expected_behavior / affected_fields 中的字段是否都在响应 proto 中?
2. 字段命名校验:字段名是否与 proto 中完全一致(区分大小写)?
3. 任一校验失败,禁止继续生成,必须先修正字段

待确认项标注规范:
以下信息若无法从现有文档/代码中直接确认,必须标注 [待确认: 需开发确认],禁止虚构:

信息项 示例 标注方式
Apollo Key fix_eventtype5_parseforkpoint_gray_switch [待确认: 需开发确认] Apollo Key
日志关键字 SetmultiRoadsForkPoints event_type=5 [待确认: 需开发确认] 日志关键字
白名单内容 具体城市/用户群体 [待确认: 需开发确认] 白名单
字段存在性 不确定某字段是否在协议中 必须先查询 proto 确认,不能标注待确认

> 日志关键字获取方式:优先读取 sourceFiles 中的源码,搜索 LOG / WARN / ERROR / INFO 等日志输出语句,提取实际日志格式。若源码不可读或未找到相关日志,则标注 [待确认: 需开发确认]。

模板文件位置:testing/test-plan-writer/test-plan-template.md

Step 7: 自检与输出

生成完成后,AI 自检以下项。以下检查项为阻塞项,任一项未通过必须修正后方可输出:

  • [ ] feature 字段与目录名一致
  • [ ] test_scenarios 非空,每个场景有完整字段
  • [ ] data_filter_conditions 与 test_scenarios 一一对应
  • [ ] data_filter_conditions 中的字段均为请求协议中实际存在的字段(无 C++ 内部变量)
  • [ ] 功能开关控制 完整(开关类型、白名单/实验组信息)
  • [ ] 测试策略 已根据变更类型自动判断(Diff / 功能 Case / 回归 / 压测),且判断依据明确
  • [ ] required_phases 与测试策略一致
  • [ ] risk_level 评估有依据
  • [ ] Diff 预期结果完整性:diff_config 中每个 diff 类型场景都有对应的预期差异定义(含场景ID、字段、基线值、目标值、变化方向)
  • [ ] AB 实验对照组预期:若为 AB 实验,对照组的预期差异明确为 UNCHANGED(与基线一致)
  • [ ] 代码 diff 分析(阻塞项):若 sourceFiles 非空或 git diff HEAD 可执行,已从 diff 中提取实际日志关键字和 Apollo Key;禁止在已执行 diff 分析的情况下仍标注 [待确认: 需开发确认]
  • [ ] 预期结果量化(阻塞项):每个 expected_behavior 包含具体数值、状态或范围;无"正常"、"有效"、"正确"等模糊描述;若无法量化,说明中已写明量化困难原因和替代验证方式
  • [ ] 内部状态识别(阻塞项):designDoc 中提到的内部状态(如"版本切换"、"已走过的 link")已通过识别方法或场景合并处理;trigger_condition 中无无法从请求字段推断的内部状态
  • [ ] 协议字段存在性(阻塞项):trigger_condition 中的字段均在请求协议中存在;expected_behavior / affected_fields 中的字段均在响应协议中存在;无虚构字段;字段名大小写与 proto 一致
  • [ ] 日志关键字来源:若使用了日志验证,日志关键字已标注 [待确认: 需开发确认] 或已读取源码/diff 确认
  • [ ] Apollo Key 来源:若提到了灰度开关/AB实验,Apollo Key 已标注 [待确认: 需开发确认] 或已从 diff 中提取实际值
  • [ ] 新字段知识库同步:若使用了本次需求新增的字段,已通过 /index 同步到 LLM-Wiki navi-guide-qa-knowledge(或已标注 [新增字段: 待 LLM-Wiki 同步])

自检失败处理流程:
1. 标记失败的检查项
2. 返回对应 Step 修正(字段问题 → Step 2.5/Step 3,日志问题 → 读取源码或标注待确认)
3. 重新执行自检,直至全部通过

执行日志(必须包含在输出中,便于审计):

## 执行日志

### 检查清单 A:代码 diff 分析
- [✅/❌/⚠️] 读取 sourceFiles:`ng_crossfinder_strategy.cpp`
- [✅/❌/⚠️] 搜索日志关键字:找到 `LOG(INFO) << "SetmultiRoadsForkPoints event_type="`
- [✅/❌/⚠️] 搜索 Apollo Key:找到 `GetConfig("fix_eventtype5_parseforkpoint_gray_switch")`
- [✅/❌/⚠️] 搜索分支逻辑:找到 `if (event_type == 5)`

### 检查清单 B:字段存在性确认
- [✅] Thrift 搜索 `event_type`:找到 `NaviGuideRequest` line 332
- [✅] Proto 搜索 `eventType`:找到 `RouteGuidanceInfo` line 1617
- [✅] Proto 搜索 `multiRoadsForkPoints`:找到 `RouteGuidanceInfo` line 1610
- [✅] 建立字段来源表:已完成(4 个字段全部确认)

### 检查清单 C:预期结果量化
- [✅] S001 expected_behavior:`multiRoadsForkPoints.size() >= 1`(已量化)
- [✅] S002 expected_behavior:`eventType == 5`(已量化)
- [⚠️] S003 expected_behavior:`与基线一致`(降级为警告,原因:回归场景无具体数值可量化)

### 场景细分检查
- [✅] 触发条件相同处理:S001-S005 的 trigger_condition 均为 `event_type == 5`,已合并为统计方式
- [✅] 灰度开关覆盖:已覆盖关闭/开启生效/开启未生效 3 个场景
- [✅] 边界维度:覆盖数量边界(0/1/多个)和空间边界(起点/中途/终点)

### 质量门禁
- [✅] 待确认项数量:2 项(白名单内容、日志关键字精确格式)
- [✅] 模糊描述检查:无模糊词
- [✅] 字段存在性:无虚构字段

> 作用:便于用户检查 AI 是否真的执行了关键步骤,便于事后审计和改进。

输出摘要(告知用户,无需确认):

测试方案已生成:

【功能概述】<简述>
【测试场景】共 X 个场景(P0: a个, P1: b个, P2: c个)
【功能开关】<开关类型> / <Apollo Key>
【测试策略】(已自动判断)
  - Diff 对比: 是/否
  - 功能 Case: **必须执行**
  - 回归测试: 是/否
【风险等级】<low/medium/high>
【执行阶段】required_phases = [...]

任一自检失败,重新生成并标注修正点。


输出校验

生成完成后,自检以下项:

  • [ ] feature 字段与目录名一致
  • [ ] test_scenarios 非空,每个场景有完整字段
  • [ ] data_filter_conditions 与 test_scenarios 一一对应
  • [ ] data_filter_conditions 中的筛选字段均为请求协议中实际存在的字段
  • [ ] required_phases 包含 Phase 1(自身)
  • [ ] risk_level 评估有依据(引用改动范围或影响面)
  • [ ] 筛选映射表 中每条预期差异都有场景对应
  • [ ] trigger_condition 字段均为请求协议字段,expected_behavior / affected_fields 字段均为响应协议字段
  • [ ] 无虚构字段,字段名大小写与 proto 一致
  • [ ] 日志关键字和 Apollo Key 已确认或已标注 [待确认: 需开发确认]

校验失败处理:
1. 标注具体失败项和原因
2. 返回对应 Step 修正
3. 重新校验直至全部通过


产出清单

产物 路径
测试方案 <CASE_DIR>/<feature>/test_plan.md

常见问题

5 问
答案由本站依据条目字段整理
Test Plan Writer怎么安装?

在支持 Skills 的客户端里执行:skillhub install user_3ddd765c/test-plan-writer。安装方式为未标注。装完刷新技能列表或重开客户端。

Test Plan Writer支持哪些客户端?

资料没有标注宿主客户端,但只要客户端支持 Skills(Claude、Codex、Cursor 等),一般都能加载。

Test Plan Writer权限高吗,安全吗?

权限级别为未标注权限。安装前先看它会读取或写入哪些内容。

Test Plan Writer收费吗?

本站不代收费用,也没有标注具体价格。是否收费取决于技能本身和所用的模型或客户端,正式使用前按作者说明确认。

Test Plan Writer用什么许可证?

许可证标注为 未说明(许可证不明确)。商用或二次分发前请到仓库确认条款原文。

热门专题

按场景挑技能
全部专题 →

技能内容以作者仓库为准;分类、权限级别与许可证状态的中文说明为中文整理,最近核验 未标注。