INTERFACE_TEST_REPORT.md 7.9 KB

CFC 小程序端接口测试报告(冒烟级 · 远程 cfc.iwintrue.com)

生成时间:2026-10-27 · 测试方式:基于页面功能定义的操作接口冒烟测试 交付物:ops_interface_smoke.py(脚本)、interface_test_report.tsv(原始 1000 行结果)、INTERFACE_TEST_MATRIX.md(页面→接口映射)、本报告

1. 测试目标与范围

  • 目标:依据小程序页面功能定义,对 cfc 后端操作接口做连通性 + 基本正确性冒烟测试。
  • 范围来源:
    • 从 cfc-frontend/utils/api.js 全量解析接口(766 个导出函数 / 769 处请求 / 756 个唯一 method+path / 103 个模块)。
    • 扫描 498 个页面 .vue/.js 得到真实的「页面路由 → 接口」调用映射。
    • 生成 1000 个接口用例,覆盖 263 个页面路由(剔除前端 __tests__ 测试文件后真实页面用例 884 个)。
  • 环境:远程 cfc.iwintrue.com 解析至 192.168.16.251;后端开启 wechat.test-mode=true,脚本用 wechat-login 空 body 自动获取 parent 角色 token 复用。

2. 测试方法与局限(重要,请先读)

每个用例以空 body {} POST 调用(与前端 request(path, 'POST') 默认空对象一致),携带 JWT token。判定标准:HTTP 200 且返回 Result 结构且 code==200 → BIZ_OK,其余按业务码分类。

本报告是冒烟级,非业务级,以下局限直接影响结论解读:

  1. 空 body:400 绝大多数为「缺参」(预期,非 bug);500 表示异常/边界输入下服务端未受控(真实健壮性信号,但需带参复测确证)。
  2. 单一 parent token:教师 / 管理员专属接口被拒返回 403(部分预期)。
  3. 外部依赖:AI/LangGraph、微信支付、OSS 等若测试环境未部署,关联接口会 500(环境缺失,非代码 bug)。
  4. __tests__ 测试文件:前端单测中引用的接口(116 个)一并纳入扫描,已在「真实页面用例(884)」统计中剔除。

3. 总体结果

类别 全部用例 (1000) 真实页面用例 (884)
BIZ_OK (code=200) 536 481
BIZ_FAIL 434 383
├─ 其中 500 服务端异常 379 339
├─ 其中 400 缺参 39 32
├─ 其中 403 权限 12 10
├─ 其中 410 业务态 2 1
└─ 其中 4001 2 1
NOT_FOUND (404) 23 14 个唯一 path
CONN_ERR (连接被重置/超时) 7 6
业务成功率 (code=200) 53% 54%

4. 发现与分类

4.1 ⚠️ 404 接口未部署 / 契约缺失(真实问题,建议优先排查)

前端(含测试)调用、但后端返回 404 的唯一路径(:var 为路径参数占位):

接口路径 说明
/api/user/switch-to-child 角色切换(家长↔孩子视角)
/api/user/switch-role 同上
/api/user/switch-mode 同上
/api/user/switch-back-to-parent 同上
/api/guide/families 规划师绑定家庭列表
/api/guide/bind/confirm 规划师绑定确认
/api/guide/families/:var/members 规划师查家庭成员
/api/guide/families/:var/plans/:var/update 规划师更新计划
/api/guide/families/:var/plans/pending 规划师待审计划
/api/guide/orders/list / stats 规划师订单
/api/health-plan/available-teachers 健康计划可选规划师
/api/health/report/bodyfat-save 体脂报告保存
/api/packages 套餐(家长代付/发布)
/api/rewards 心愿奖励
/api/wishes/:var/price 心愿改价

解读:这些接口被前端调用却返回 404,说明前后端契约不一致(后端未实现 / 路径已变更 / 版本不一致)。特别是 4 个 user/switch-* 角色切换接口缺失,会直接影响「家长↔孩子视角切换」核心功能。

4.2 ⚠️ 500 服务端异常(339 个真实页面用例,占比 38%)

按模块分布(Top):health 53、family 35、activity 18、home 16、product 16、guide 16、circle 14、orchestration 14、wishes 11、cognitive 10 … 共涉及 55 个模块,仅有 4 个明确属于外部依赖(如 /api/ai/* 指向 LangGraph,测试环境未部署)。

解读:空 body 下大量接口抛 500 而非受控的 400,说明后端缺少统一的入参校验与全局异常处理(异常输入未经 Result 包装直接抛出)。这是系统性质量缺陷。需带真实参数 + 按模块逐批复测,区分:

  • (a) 代码健壮性 bug(空指针 / 类型转换)—— 应修复;
  • (b) 环境依赖缺失(AI/支付/微信未配)—— 应补齐环境或降级返回明确错误。

4.3 403 权限(8 个唯一 path)

  • /api/admin/*(管理员)、/api/guide/*(规划师)被 parent token 拒绝 —— 预期。
  • 例外:/api/articles/detail 返回 403 值得确认(文章详情应可公开或登录后访问,不该被拒)。

4.4 400(32 个)—— 空 body 缺参,非 bug,属冒烟局限。

5. 五要素问题清单(精选代表性)

问题 1|角色切换接口契约缺失 ① 问题描述:家长端「切换孩子视角」功能依赖的 4 个 /api/user/switch-* 接口全部返回 404。 ② 测试点:ops_interface_smoke.py 用例 user :: switchToChild / switchRole / switchMode / switchBackToParent,响应 HTTP 404。 ③ 最优方案:确认后端是否已迁移/重命名这些接口(AGENTS.md 提及「双角色切换」是核心特性),修复路由或同步前端调用路径。 ④ 目的:恢复家长↔孩子视角切换核心功能,消除前后端契约缺口。 ⑤ 闭环:后端补路由后,用 parent token 复测 code==200。

问题 2|健康模块接口健壮性(大量 500) ① 问题描述:health 模块 53 个接口在空 body 下返回 500,疑似缺参校验/空指针。 ② 测试点:/api/health/* 系列(report/meal/exercise/sleep 等),响应 HTTP 200 + code=500。 ③ 最优方案:为 health 模块补齐 DTO 校验(@Valid)与全局异常处理器,使缺参返回 code=400 而非 500。 ④ 目的:提升后端在异常输入下的可控性,避免对外暴露 500。 ⑤ 闭环:带参复测 + 注入异常输入压测,确认 code=400 且日志无未捕获异常。

问题 3|文章详情权限异常 ① 问题描述:/api/articles/detail 带有效 parent token 仍返回 403。 ② 测试点:articles :: getArticleDetail,HTTP 200 + code=403。 ③ 最优方案:核对 JwtInterceptor 公开路径列表与文章详情的权限配置,确认是否误拦截。 ④ 目的:保证文章详情对登录用户可见(前端文章中心强依赖)。 ⑤ 闭环:复测确认登录态下 code==200。

6. 结论

冒烟级结论:接口整体连通正常(54% 直接 code=200),但同时暴露三类可立即行动的工程问题:

  1. 前后端契约缺失(404):15 个前端调用的接口后端无路由(含核心的角色切换 4 个)。
  2. 服务端健壮性(500 占比 38%):大量接口在边界/空输入下抛 500,缺统一校验与全局异常处理。
  3. 角色权限:需确认 /api/articles/detail 等的 403 是否为配置错误。

下一步建议:以本报告为基线,下阶段做业务级接口测试——带真实参数 + 多角色(parent/teacher/child)token,对 339 个 500、15 个 404、8 个 403 逐接口确证是代码 bug、环境缺失还是角色因素,形成可派发的缺陷清单。

7. 复跑命令

# 在能直连 192.168.16.251 的环境(前台运行,沙箱后台会拦截该内网 IP)
python ops_interface_smoke.py --base http://192.168.16.251 --host cfc.iwintrue.com \
       --auto-login --timeout 3 --report interface_test_report.tsv
# 只测某页面: --only-page pages/health
# 指定路径参数占位: --param-val <真实ID>