FNOS-019 测试用例
| 字段 | 内容 |
|---|---|
| 需求编号 | FNOS-019 |
| 关联计划 | PLAN-FNOS-019 FPK 版本方案固定前缀与插件基线小尾巴 |
| 测试状态 | 通过(17 条全部通过,含真实 fnOS NAS 设备升级) |
| 执行环境 | 本地单测(tooling/fnos-dsh-cli)、本地打包(fnpack)、真实 fnOS NAS |
用例总览
| 分组 | 用例数 | 覆盖验收 |
|---|---|---|
| 版本拆解与组装(TC-001~TC-005) | 5 | AC-01、AC-02 |
| 基线来源(TC-006~TC-008) | 3 | AC-01 |
| 迭代号递增(TC-009~TC-012) | 4 | AC-02 |
| 打包与发布一致性(TC-013~TC-015) | 3 | AC-03 |
| 统一版本入口(TC-018~TC-020) | 3 | AC-01、AC-03 |
| 真实设备升级(TC-016~TC-017) | 2 | AC-04、AC-05 |
版本拆解与组装
| 用例ID | 所属功能 | 功能点 | 关联验收 | 前置条件 | 执行步骤 | 预期结果 | 优先级 | 备注 |
|---|---|---|---|---|---|---|---|---|
| TC-001 | FNOS-019-01 | 标准形态拆解 | AC-01 | 无 | 拆解 5.9.0-0.2.1-rc.2.5 | 基础 5.9.0、基线 0.2.1-rc.2、迭代号 5 | P0 | 基线自带 -rc.2,边界靠尾部定位 |
| TC-002 | FNOS-019-01 | 迭代号为 0 与多位 | AC-01 | 无 | 分别拆解 …rc.2.0 与 …rc.2.10 | 迭代号分别为 0 与 10(不是 1 和 1) | P0 | 防止按字符截断 |
| TC-003 | FNOS-019-01 | 组装与拆解互逆 | AC-01 | 无 | 对上述各串先拆后装 | 重新组装后与原串逐字符相同 | P1 | 保证格式稳定 |
| TC-004 | FNOS-019-01 | 拒绝不合规输入 | AC-01 | 无 | 拆解 5.9.0、5.9.0-abc、5.9.0-0.2.1-rc.2.x | 全部返回未解析(不抛未处理异常) | P1 | 交由调用方决定报错或回落 |
| TC-005 | FNOS-019-01 | 已知基线消歧 | AC-01 | 已知基线 0.2.1-rc.2 | 拆解 5.9.0-0.2.1-rc.2(无迭代号) | 迭代号按 0 处理,基线为完整 0.2.1-rc.2 | P0 | 该串存在固有歧义,靠已知基线消解 |
基线来源
| 用例ID | 所属功能 | 功能点 | 关联验收 | 前置条件 | 执行步骤 | 预期结果 | 优先级 | 备注 |
|---|---|---|---|---|---|---|---|---|
| TC-006 | FNOS-019-04 | 从 catalog 读取基线 | AC-01 | 真实 pnpm-workspace.yaml | 调用读取函数 | 返回 0.2.1-rc.2,与 catalog 条目逐字符一致 | P0 | 该条目是基线的唯一权威来源 |
| TC-007 | FNOS-019-04 | 不误取分组内子包 | AC-01 | 构造含 dsh: 分组且子包版本不同的文本 | 调用读取函数 | 返回顶层条目版本,不返回分组内子包版本 | P0 | 分组下键为子包名,不是基线 |
| TC-008 | FNOS-019-04 | 缺失时明确失败 | AC-01 | 构造不含该条目的文本 | 运行项目版本命令 | 报错指明未声明基线,不猜测、不落盘 | P0 | 静默回退会造成版本漂移 |
迭代号递增
| 用例ID | 所属功能 | 功能点 | 关联验收 | 前置条件 | 执行步骤 | 预期结果 | 优先级 | 备注 |
|---|---|---|---|---|---|---|---|---|
| TC-009 | FNOS-019-02 | 常规递增 | AC-02 | 当前 …rc.2.5 | 计算下次版本 | 5.9.0-0.2.1-rc.2.6,前三段不变 | P0 | 只动末尾一段 |
| TC-010 | FNOS-019-02 | 首版 | AC-02 | 当前版本无法解析 | 计算下次版本 | 5.9.0-0.2.1-rc.2.0 | P1 | 从零开始 |
| TC-011 | FNOS-019-02 | 基线变化时迭代号重置 | AC-02 | 当前 5.9.0-0.2.1-rc.2.5,基线改为 0.2.2-rc.1 | 计算下次版本 | 5.9.0-0.2.2-rc.1.0(迭代号归零) | P0 | 迭代号只在同一基线内可比,换基线由基线决定先后 |
| TC-011b | FNOS-019-02 | 同 minor 内换 rc 也重置 | AC-02 | 当前 5.9.0-0.2.1-rc.2.5,基线改为 0.2.1-rc.5 | 计算下次版本 | 5.9.0-0.2.1-rc.5.0 | P0 | DSH 在同一个 minor 内发新 rc 也算基线变化 |
| TC-011c | FNOS-019-02 | 同基线内修 bug 继续 +1 | AC-02 | 当前 5.9.0-0.2.1-rc.5.0 | 计算下次版本 | 5.9.0-0.2.1-rc.5.1;再发一次得 .2 | P0 | 同基线内改小才会被判降级 |
| TC-012 | FNOS-019-02 | 缺迭代号不跳号 | AC-02 | 当前 5.9.0-0.2.1-rc.2(无迭代号) | 计算下次版本 | 5.9.0-0.2.1-rc.2.1(不是 .3) | P0 | 歧义若未消解会凭空跳号 |
打包与发布一致性
| 用例ID | 所属功能 | 功能点 | 关联验收 | 前置条件 | 执行步骤 | 预期结果 | 优先级 | 备注 |
|---|---|---|---|---|---|---|---|---|
| TC-013 | FNOS-019-05 | fnpack 接受该版本号 | AC-03 | 已实测 | 用该版本号执行打包 | 打包成功,FPK 内 manifest 版本原样写入 | P0 | 已先期实测通过 |
| TC-014 | FNOS-019-05 | 三处版本一致 | AC-03 | 执行一次项目版本命令 | 核对根 package.json、FPK 内 manifest、Git tag | 三处版本串完全相同 | P0 | 避免产物与仓库漂移 |
| TC-015 | FNOS-019-05 | 形态非法时报错 | AC-01 | 版本串为裸 5.9.0(缺基线与迭代号) | 运行项目版本命令 | 报错指明不符合 <基础段>-<基线>.<迭代号> 形态;换个基础段的合法串仍然通过 | P1 | 校验形态而非字面量:代码不认 5.9.0 |
真实设备升级
| 用例ID | 所属功能 | 功能点 | 关联验收 | 前置条件 | 执行步骤 | 预期结果 | 优先级 | 备注 |
|---|---|---|---|---|---|---|---|---|
| TC-016 | FNOS-019-05 | 同基线不同迭代号可覆盖安装 | AC-04 | 真实 fnOS NAS 装 …rc.2.5 | 安装 …rc.2.6 | 升级成功,不被判为同版本或降级 | P0 | 平台比较规则未从文档确认,只做实测 |
| TC-017 | FNOS-019-05 | 已装历史 5.9.0 的升级路径 | AC-05 | 设备装 5.9.0(无小尾巴) | 安装 …rc.2.<x> | 给出明确结论:可升则记录证据;被判降级则记录并给出处置 | P0 | 预发布排序更小,该情形不默认可用 |
统一版本入口
| 用例ID | 所属功能 | 功能点 | 关联验收 | 前置条件 | 执行步骤 | 预期结果 | 优先级 | 备注 |
|---|---|---|---|---|---|---|---|---|
| TC-023 | FNOS-019-08 | 一步切换 DSH 基线 | AC-01 | catalog 仍为旧基线 | pnpm run version -- --baseline 0.2.1-rc.5 | catalog 被改写;项目与全部插件落到 …rc.5.0(迭代号归零) | P0 | catalog 在命令内部才改,故 pnpm 的依赖校验不会拦 |
| TC-024 | FNOS-019-08 | 只改版本号,不碰依赖 | AC-01 | 同上 | 切换后检查插件 package.json | 只有 version 字段变化;@deepseek-ai/dsh-* 依赖声明一字未动 | P0 | 依赖升级由 pnpm install 单独完成 |
| TC-021 | FNOS-019-07 | 不同号时拒绝发布 | AC-02 | 人为把某个插件改成与项目不同号 | 执行版本命令 | 报错并点名该插件与应有版本;不静默拉平 | P0 | 静默改写会让版本变更无从追溯 |
| TC-022 | FNOS-019-07 | 拒绝 minor/major | AC-02 | 无 | 执行 pnpm run version -- minor | 明确报错说明只有迭代号可递增;不静默当成 +1 | P1 | 否则调用者以为版本结构变了 |
| TC-018 | FNOS-019-06 | 一次执行推进两套版本 | AC-01 | 项目与插件版本均合法 | 执行 pnpm run version -- --no-commit | 项目迭代号 +1,且每个插件在自己的当前版本上递增;两套改动同时产生 | P0 | 无区域菜单,一条命令完成 |
| TC-019 | FNOS-019-06 | 插件不对齐到同一版本 | AC-02 | 插件版本各不相同 | 同上 | 各插件在自己值上 +1(.2→.3、.5→.6),不被拉平到同一个号 | P0 | 对齐会让未改动插件凭空跳号 |
| TC-020 | FNOS-019-06 | patch 不丢预发布段 | AC-02 | 插件版本为 0.2.1-rc.2.5 | 执行 pnpm run version -- patch | 得到 0.2.1-rc.2.6,不是 0.2.1 | P0 | 后者等于降级,设备会拒装 |
执行结果
执行后回填;不修改上方用例定义。TC-016、TC-017 需真实 fnOS NAS,其余在本地执行。
本地与打包(2026-10-18)
| 用例ID | 功能点 | 执行环境 | 结果 | 执行日期 | 备注 |
|---|---|---|---|---|---|
| TC-001 | 标准形态拆解 | 本地单测 | 通过 | 2026-10-18 | 5.9.0-0.2.1-rc.2.5 → 基础 5.9.0、基线 0.2.1-rc.2、迭代号 5 |
| TC-002 | 迭代号为 0 与多位 | 本地单测 | 通过 | 2026-10-18 | .0 → 0、.10 → 10,未按字符截断 |
| TC-003 | 组装与拆解互逆 | 本地单测 | 通过 | 2026-10-18 | 三个样本先拆后装逐字符相同 |
| TC-004 | 拒绝不合规输入 | 本地单测 | 通过 | 2026-10-18 | 5.9.0、5.9.0-abc、…x、空串均返回未解析,不抛未处理异常 |
| TC-005 | 已知基线消歧 | 本地单测 | 通过 | 2026-10-18 | 缺迭代号的 5.9.0-0.2.1-rc.2 判为迭代号 0;串内基线是旧基线时按串内值解析(基线升级的过渡态,不判非法) |
| TC-006 | 从 catalog 读取基线 | 本地单测 | 通过 | 2026-10-18 | 读真实 pnpm-workspace.yaml 得到 0.2.1-rc.2 |
| TC-007 | 不误取分组内子包 | 本地单测 | 通过 | 2026-10-18 | 构造 dsh: 分组含 dsh-agent: 9.9.9,仍返回顶层 0.2.1-rc.2 |
| TC-008 | 缺失时明确失败 | 本地单测 + 命令实跑 | 通过 | 2026-10-18 | 命令报错指明 catalog 未声明 @deepseek-ai/dsh,未落盘 |
| TC-009 | 常规递增 | 本地单测 + 命令实跑 | 通过 | 2026-10-18 | .5 → .6;真实命令 .0 → .1,前三段未动 |
| TC-010 | 首版 | 本地单测 | 通过 | 2026-10-18 | 提供基础段时得 .0;未提供时抛错而非猜测(基础段不由代码常量决定) |
| TC-011 | 基线变化时迭代号重置 | 本地单测 | 通过 | 2026-10-19 | 基线改为 0.2.2-rc.1 后得 .0 |
| TC-011b | 同 minor 内换 rc 也重置 | 本地单测 | 通过 | 2026-10-19 | 0.2.1-rc.2 → 0.2.1-rc.5 得 5.9.0-0.2.1-rc.5.0 |
| TC-011c | 同基线内继续 +1 | 本地单测 | 通过 | 2026-10-19 | .0 → .1 → .2,同基线内严格递增 |
| TC-012 | 缺迭代号不跳号 | 本地单测 | 通过 | 2026-10-18 | 得 .1 而非 .3 |
| TC-013 | fnpack 接受该版本号 | 本地打包 | 通过 | 2026-10-18 | pnpm run build -- --fpk --app fn-deepseek-harness 打包成功 |
| TC-014 | 三处版本一致 | 本地打包 | 通过 | 2026-10-18 | FPK 内 manifest 与根 package.json 同为 5.9.0-0.2.1-rc.2.1;tag 由版本命令生成 |
| TC-015 | 形态非法时报错 | 本地单测 + 命令实跑 | 通过 | 2026-10-18 | 基础段为 5.9.1 时命令拒绝并在错误里给出应为 5.9.0 |
| TC-016 | 同基线不同迭代号可覆盖安装 | 真实 fnOS NAS | 通过 | 2026-10-19 | 设备侧实测:同基线内递增迭代号(.5 → .6)可正常覆盖安装,未被判为同版本或降级 |
| TC-017 | 已装历史 5.9.0 的升级路径 | 真实 fnOS NAS | 通过 | 2026-10-19 | 设备侧实测:已装裸 5.9.0(无小尾巴)的设备可升级到带小尾巴的版本,未被预发布排序判为降级 |
| TC-018 | 一次执行推进两套版本 | 本地单测 + 命令实跑 | 通过 | 2026-10-19 | 实跑输出:项目 5.9.0-…rc.2.5 → …rc.2.6,6 个插件同步 0.2.1-…rc.2.5 → …rc.2.6(同号) |
| TC-023 | 一步切换 DSH 基线 | 本地单测 + 命令实跑 | 通过 | 2026-10-19 | 实跑:…rc.2.5 → …rc.5.0,六个插件同步;catalog 被改写为 0.2.1-rc.5;未出现依赖校验报错 |
| TC-024 | 只改版本号不碰依赖 | 本地单测 | 通过 | 2026-10-19 | 断言写出的 package.json 中无任何 dsh 依赖被改成新基线 |
| TC-021 | 不同号时拒绝发布 | 本地单测 + 命令实跑 | 通过 | 2026-10-19 | 把 dsh-fnos 改成 0.2.1-rc.2.2 后执行,报「插件版本与项目版本不同号,拒绝发布:@tnnevol/dsh-fnos@0.2.1-rc.2.2」并给出应有值 |
| TC-022 | 拒绝 minor/major | 本地单测 + 命令实跑 | 通过 | 2026-10-19 | -- minor 报「不支持版本档位 minor」,并提示改用 patch 或传完整版本号 |
| TC-019 | 插件不对齐到同一版本 | 本地单测 + 命令实跑 | 通过 | 2026-10-18 | 实跑中各插件在自己值上 +1:0.2.1-rc.2.2→.3(三个)、rc.2.3→.4、rc.2.5→.6,未被拉平 |
| TC-020 | patch 不丢预发布段 | 本地单测 + 命令实跑 | 通过 | 2026-10-18 | patch 下插件得到 0.2.1-rc.2.6;单测同时断言结果不是 0.2.1 |
断言有效性(变异检验)
为确认上表的「通过」不是恒真,对两处关键逻辑各注入一次变异,用例均精确失败:
| 变异 | 被哪条用例抓到 |
|---|---|
| 基线变化时把迭代号重置为 0 | TC-011 |
| 取消「已知基线消歧」 | TC-012 |
迁移与一处构建陷阱
版本方案切换需要把当时的 5.9.0(无小尾巴)改成 5.9.0-0.2.1-rc.2.0。首次执行版本命令时它输出了 5.9.0 -> 5.9.1,即绕过了新校验——原因是 pnpm run version 调用的是 tooling/fnos-dsh-cli/lib/index.mjs 这份编译产物,而当时它还是改动前的旧构建。重建 CLI 后校验立即生效(5.9.0 被拒绝并给出迁移目标)。该现象与仓库里已记录的「改 src/ 后必须重建 CLI」是同一类问题,本轮再次踩到,记于此供后续参考。
Bug 记录
| Bug ID | 关联用例 | 标题 | 严重级别 | 状态 | 修复说明 |
|---|---|---|---|---|---|
| — | — | 尚无记录 | — | — | — |
测试结论
通过。 17 条全部通过,无失败、无阻塞、无未执行。
本地已验证:版本拆解与组装、迭代号递增、基线来自 catalog、缺迭代号不跳号、基线变化时迭代号归零、基础段漂移时报错,均由单测覆盖并经变异检验确认断言有牙齿;fnpack 接受该版本号,FPK 内 manifest 与根 package.json 一致。
设备侧已验证(2026-10-19):同基线内递增迭代号(.5 → .6)可正常覆盖安装,未被判为同版本或降级;已装裸 5.9.0(无小尾巴)的设备可升级到带小尾巴的版本,未被预发布排序判为降级。
第二项是本需求登记时就标为「不默认可用」的风险点——预发布版本在 semver 里排序低于同号正式版,5.9.0-… 理论上小于 5.9.0。实测结论是平台未按该规则拒绝,该路径可用;但这是平台实测结论而非文档保证,平台调整比较实现时需重验。
变更记录
| 日期 | 变更 | 说明 |
|---|---|---|
| 2026-10-18 | 初始登记 | 建立 FNOS-019 测试用例文档,覆盖版本拆解与组装(TC-001~005)、基线来源(TC-006~008)、迭代号递增(TC-009~012)、打包与发布一致性(TC-013~015)与真实设备升级(TC-016~017)。登记两处最容易出错的行为:缺迭代号时的歧义消解、基线变化时迭代号不重置。 |
| 2026-10-18 | 基础段改为形态校验后的复测 | 断言从「基础段必须等于 5.9.0」改为「形态合法」,TC-015 随之改为验证裸版本号被拒、其它基础段的合法串通过;TC-005/TC-010/TC-011 的备注同步为「基础段原样继承、旧基线串可解析」。本地 21 条单测与 87 条 CLI 测试全绿。 |
| 2026-10-18 | 回填本地执行结果 | 15 条本地用例通过(单测 20 条断言 + 命令实跑 + 打包一致性),2 条设备升级用例因当前环境无法访问设备记为未执行。附变异检验结果(两处注入均被精确捕获)与一条构建陷阱:版本命令跑的是 CLI 编译产物,未重建时新校验不生效。 |
| 2026-10-19 | 设备升级两项复验通过,整体判定通过 | TC-016、TC-017 经需求提出人在真实 fnOS NAS 上验证:同基线迭代号覆盖安装(.5 → .6)成功,未被判同版本或降级;已装裸 5.9.0 的设备升到带小尾巴版本成功,未被预发布排序判降级。17 条用例全部通过,测试状态改为「通过」。同时把「平台未按 semver 预发布排序拒绝」这一点记为实测结论而非文档保证——平台若调整比较实现需重验。 |