8.5 KiB
8.5 KiB
Function 运行时完整测试审计(2026-04-16)
1. 本次目标
本次不是泛泛地跑一遍前端页面,而是围绕“游戏运行中的 function 主链路”做系统化核查,重点确认下面 4 件事:
- 当前运行时 function 集合是否还能正确构建、过滤、排序和解析。
- function 命中的前端承接链路是否仍然稳定。
- 已服务端化的 runtime action function 是否还能闭环执行。
- 工程门禁是否处于可持续回归的状态。
2. 本次实际覆盖范围
本轮重点覆盖了这些实现入口:
src/data/stateFunctions.tssrc/data/functionCatalog/**src/data/npcInteractions.tssrc/hooks/story/**src/services/runtimeStoryService.tssrc/hooks/useGameFlow.tsserver-node/src/modules/story/**server-node/src/modules/inventory/**server-node/src/modules/runtime-item/**server-node/src/modules/quest/**scripts/smoke-server-node.ts
3. 实际执行的测试与检查
3.1 前端 Vitest 全量测试
执行命令:
npm.cmd test
结果:
110个测试文件全部通过276条测试全部通过
其中与 function 主链路直接相关、并已确认通过的测试包括:
src/data/stateFunctions.test.tssrc/data/functionCatalog/functionCatalog.test.tssrc/data/npcInteractions.test.tssrc/hooks/story/choiceActions.test.tssrc/hooks/story/storyGenerationState.test.tssrc/hooks/story/runtimeStoryCoordinator.test.tssrc/components/AdventurePanel.test.tsxsrc/services/runtimeStoryService.test.ts
补充说明:
- 运行
hostileNpcPresets.test.ts时会看到 “network disabled in test” 的日志。 - 这不是本轮失败项,测试已验证在 LLM 不可达时会正确走 deterministic fallback。
3.2 内容数据校验
执行命令:
npm.cmd run check:content
结果:
check:data通过check:overrides通过check:smoke通过- 输出为:
Content validation passed. scenes=24 monsters=16 characters=5 functions=12
结论:
- 当前基础内容数据、override 与 smoke 内容校验没有发现新的 function 数据层问题。
3.3 服务端测试
执行命令:
npm.cmd run server-node:test
结果:
108条服务端测试全部通过
本轮已确认通过的 function 相关服务端能力包括:
inventory_useequipment_equipnpc_tradenpc_giftnpc_quest_acceptnpc_quest_turn_intreasure_inspect- 战斗结算与 quest signal 推进
结论:
- 已服务端化的 runtime function 承接链路当前单测层面是稳定的。
3.4 服务端 smoke
执行命令:
npm.cmd run server-node:smoke
结果:
- 失败
- 报错:
TypeError: Cannot read properties of undefined (reading 'enabled')
3.5 TypeScript 类型检查
执行命令:
npm.cmd run typecheck
结果:
- 失败
- 失败位置:
src/hooks/useGameFlow.ts:339
3.6 生产构建
执行命令:
npm.cmd run build
结果:
- 通过
结论:
- 当前代码可构建,但并不代表类型门禁与 smoke 门禁同样健康。
4. 本轮确认的问题
P1:server-node:smoke 已失效,无法完成服务端运行时冒烟验证
- 现象:
npm.cmd run server-node:smoke无法启动临时 Express 服务,直接在createSmsVerificationService处报错。
- 直接原因:
scripts/smoke-server-node.ts里的createSmokeConfig()只构造了llm、dashScope等字段,没有补齐后续新增的smsAuth、wechatAuth、authSession配置块。server-node/src/config.ts中AppConfig已把这些字段定义为必需项。server-node/src/services/smsVerificationService.ts在createSmsVerificationService中直接读取config.smsAuth.enabled,因此 smoke 配置一进入createAppContext就会崩。
- 影响:
- 本地无法再用 smoke 脚本验证“服务端真实启动 + 认证 + runtime save/settings 回路”。
- 这会让 function 服务端化之后的真实接线路径少掉一层最接近运行时的保护。
- 判断:
- 这是本轮最明确、最稳定复现的真实 bug。
P1:typecheck 门禁已破,useGameFlow 的 starter inventory 合并存在类型漂移
- 现象:
npm.cmd run typecheck在src/hooks/useGameFlow.ts第339行失败。
- 直接原因:
- 同文件中的
mergeStarterInventoryItems<T extends { category: string; name: string }>会优先从显式 starter item 推断出一个“字段更严格”的T。 - 但 fallback 侧传入的是
InventoryItem数组,而InventoryItem.description、equipmentSlotId、runtimeMetadata等字段本身是可选的。 - 于是
explicitItems与fallbackItems在泛型推断后不再兼容,类型门禁被打穿。
- 同文件中的
- 影响:
- 当前 starter inventory 初始化链路虽然能跑、也能通过构建,但已经失去 TypeScript 对结构一致性的保护。
- 这类问题后续很容易演变成“自定义世界显式初始物品”和“默认初始物品”在字段形态上继续分叉。
- 判断:
- 这是一个真实的工程 bug,优先级高于纯测试文案问题。
5. 本轮已确认通过的结论
- state function 运行时构建、过滤、优先级、选项解析当前测试全绿。
- function catalog 文档映射、helper option、trade/gift/recruit modal helper 当前测试全绿。
- 前端 function 主链路相关测试在最新工作区状态下已全部通过。
- 服务端 runtime story action、inventory、runtime-item、quest 承接链路当前测试全绿。
- 内容数据层校验通过。
- 生产构建通过。
6. 结论
如果只看“游戏运行中的 function 主链路”,当前结论是:
- 前端 function 运行时逻辑:通过
- 服务端 function action 承接:通过
- 内容数据与 function 基础目录:通过
- 工程回归门禁:不完整
当前最需要处理的不是再扩 function 范围,而是先修复这两个门禁缺口:
- 修好
server-node:smoke的配置构造,让服务端冒烟恢复可用。 - 修好
useGameFlow的 starter inventory 类型漂移,让typecheck回到绿色基线。
7. 备注
本轮没有做两类事情:
- 没有接入真实外部 LLM 做在线回归,本轮依赖的是本地测试里已有的 fallback 断言。
- 没有人手逐个点击整局游戏所有 function 的视觉回放,本轮重点是自动化测试、服务端测试、内容校验与 smoke 门禁。
因此,本审计可以说明“当前 function 系统的自动化测试层状况”,但不等于“所有视觉演出与在线模型联动都已人工验证完毕”。
8. 执行回填(2026-04-28,修复聊天任务领取入口)
- 问题现象:
- NPC 聊天中的待领取任务,点击“查看任务”进入详情后,再点“领取任务”没有把面板切到正式已接任务状态,表现上像“无法领取”。
- 根因:
npcChatQuestOfferUi.acceptPendingOffer()会异步把npc_quest_accept发到服务端。- 但
src/components/rpg-runtime-panels/RpgAdventurePanel.tsx里“待领取任务详情弹层”的onAcceptPendingNpcQuestOffer只返回了questId,没有把它写入共享的pendingAcceptedQuestId。 - 结果是本来负责等待 quest 真正进入
quests后再统一收口面板状态的useEffect根本不会触发。
- 修复:
- 在
onAcceptPendingNpcQuestOffer中补写setPendingAcceptedQuestId(acceptedQuestId),让待领取任务详情弹层复用普通npc_quest_accept已有的异步收口链。 - 新增
src/components/rpg-runtime-panels/RpgAdventurePanel.questOffer.test.tsx,覆盖“查看任务 -> 领取任务 -> 服务端异步写回 quest log -> 面板切到正式任务状态”的回归路径。
- 在
- 本次回归验证:
src/components/rpg-runtime-panels/RpgAdventurePanel.questOffer.test.tsxsrc/components/rpg-runtime-panels/RpgAdventurePanel.test.tsxsrc/hooks/rpg-runtime-story/npcEncounterActions.test.tssrc/hooks/rpg-runtime-story/choiceActions.test.tssrc/hooks/rpg-runtime-story/runtimeStoryCoordinator.test.tssrc/hooks/rpg-runtime-story/sessionActions.test.ts- 共
57条测试通过。