4 月 18 日,我完成了一轮 HAOVP 后端接口验收。这次不是挑几个接口确认能返回数据,而是按认证与用户、内容与评论及推荐、后台管理三批执行,并把每一项的请求方法、脱敏路径、预期结果和实际状态写进 JSON 明细。
最终汇总为:
| 验收批次 | 用例数 | 通过 | 失败 |
|---|---|---|---|
| 认证与用户 | 29 | 29 | 0 |
| 内容、评论与推荐 | 63 | 63 | 0 |
| 后台管理 | 23 | 23 | 0 |
| 合计 | 115 | 115 | 0 |
这里的“通过”表示实际结果符合用例预期,不等于每个请求都返回 200。例如,无验证码登录应该被拦截,普通用户访问内部审核接口也应该被拒绝;这些负向用例在得到预期拒绝结果时同样计为通过。
先统一验收口径
接口文档中大约有 186 条 endpoint,但其中包含重复文档项、内部接口和管理接口映射,不能直接把这个数字当作实际测试数量。
我采用 JSON 明细中的独立用例作为最终口径。每条记录至少包含:
{
"method": "POST",
"path": "/example/resource",
"status": "PASSED",
"http": 200,
"note": "脱敏后的测试说明"
}这是结构示例,不是实际接口、账号或请求数据。
三份结果文件分别有 29、63 和 23 条记录,与汇总报告完全一致。这样可以避免出现“报告写了全部通过,但明细数量对不上”的问题。
为什么按模块分批执行
最初如果把所有接口放进一个长脚本,某个请求超时或状态依赖出错后,后面的结果也会受到影响。为了让问题更容易定位,我按业务链路拆成三批:
认证与用户
-> 注册、登录、刷新、资料、关注、通知、私信
内容、评论与推荐
-> 分类、标签、视频、互动、弹幕、统计、评论、推荐
后台管理
-> 管理员认证、用户治理、内容审核、评论管理、仪表盘分批后,每一批都可以独立准备数据、执行、清理和重测。某一模块失败时,不需要从头运行全部用例。
不是只测正常请求
如果只验证合法请求返回成功,很难判断认证和权限控制是否真正生效。这次验收同时包含正向和负向场景。
例如:
- 合法验证码和账号能够登录;
- 缺少验证码的登录请求会被拦截;
- 刷新令牌能够换取新的认证信息;
- 用户被禁用后不能继续登录;
- 后台重置密码后可以使用新密码登录;
- 普通用户访问内部审核接口会被拒绝;
- 内容置顶操作必须满足作者身份和正确的资源关系。
因此,不能用“HTTP 状态不是 200”直接判断用例失败。验收器需要同时比较预期 HTTP 状态、业务状态和业务前提。
一个简化判断可以写成:
boolean passed = actualHttp == expectedHttp
&& matchesExpectedBusinessState(response)
&& verifySideEffect();真正的验收还要检查数据库或后续查询中的副作用,不能只看响应正文。
第一类问题:运行代码和本地源码不一致
排查用户和评论链时,我发现部分容器运行的还是旧构建产物,与本地源码不一致。
这种问题很容易造成错觉:代码中明明已经修复,接口行为却没有变化;继续修改源码,只会让排查方向越来越偏。
我先重新构建产物并更新运行环境,再核对服务实际加载的版本。以后遇到类似情况,我会先检查:
当前提交版本
-> 构建产物生成时间
-> 镜像或容器中的文件
-> 服务启动日志
-> 实际接口行为只有这几层一致,才适合继续判断代码逻辑。
第二类问题:公开接口被认证规则挡住
用户公开资料、关注列表、分类树和标签列表等接口,本来需要允许未登录访问,但实际运行时受到认证规则限制。
修复这类问题不能简单扩大白名单。每个接口都要先确认:
- 返回内容是否确实允许公开;
- 是否需要隐藏敏感字段;
- 路径变量能否访问其他用户的数据;
- 查询量是否需要限制;
- 写操作是否仍然要求认证和权限。
公开读取接口和内部管理接口必须保持边界。验收通过的是指定公开路径,不代表整个模块都应跳过认证。
第三类问题:跨服务返回值判断错误
内容链中曾出现视频详情和列表里的用户展示信息为空。调用用户服务本身有返回,但成功分支没有进入。
根因是对包装类型状态码使用了不合适的比较方式。跨服务反序列化后得到的是对象,不能依赖对象引用相同来判断数值相等。
// 容易产生问题
if (result.getCode() == expectedCode) {
// ...
}
// 更明确的数值判断
if (Objects.equals(result.getCode(), expectedCode)) {
// ...
}这是简化示例,不对应实际类名和常量。
这次问题提醒我:接口已经返回 200,不代表业务分支一定执行正确。还要检查关键字段是否完整、远程结果是否被正确解释。
第四类问题:事务内同步回写造成等待
收藏链曾在主事务中同步调用其他服务更新统计,出现锁等待和慢失败。调整后,把非核心的同步回写移到事务提交之后,并以异步尽力执行的方式处理。
完成核心数据库事务
-> 事务提交
-> 异步通知统计更新
-> 失败时记录并等待后续补偿这种方式缩短了主链路,但它不是强一致方案。异步调用失败时,统计值可能暂时不一致,因此还需要日志、重试或对账机制。
本轮能够确认的是接口链路已经恢复;异步调用失败后的重试、补偿和对账仍要继续验证。
第五类问题:业务前提不成立导致误判
评论置顶和取消置顶曾被记录为失败。重新检查后发现,这类操作要求当前用户是视频作者,并且评论确实属于传入的视频。
如果测试账号身份或资源关系不满足要求,接口拒绝请求是正确行为,不应该算作系统缺陷。
因此,用例不仅要保存请求参数,还要明确前置关系:
测试用户身份
目标资源归属
数据当前状态
前置操作是否成功
预期允许或拒绝服务端也补充了资源归属校验,避免仅凭一个资源编号执行跨资源操作。
第六类问题:数据映射和数据库约束
推荐兴趣更新曾因 MyBatis 对映射集合的遍历写法不正确而失败。后台审核链还发现调用方没有传递管理员身份,以及审核记录外键指向了不合适的用户表。
这两类问题分别属于:
- Java 数据结构与 SQL 映射不一致;
- 服务身份与数据库关系模型不一致。
修复后不能只重跑最初失败的一个接口,还要继续验证:
- 数据是否真正写入正确表;
- 关联字段是否指向正确主体;
- 查询能否读回刚写入的数据;
- 无权限主体是否仍会被拒绝;
- 删除或状态变更是否破坏关联数据。
接口返回成功只是起点,数据关系正确才是完整结果。
消息组件异常时的降级边界
验收期间,消息路由仍存在异常。内容服务补充了主表降级更新,使相关计数在当前请求链中能够变化。
这说明本轮接口用例可以得到预期结果,但不能反推消息组件已经恢复正常。两种状态必须分开记录:
业务接口结果符合预期
≠
所有下游组件均处于正常状态降级路径让核心结果暂时可用,也可能带来重复更新、异步事件丢失或状态来源不统一等新问题。消息链本身仍需要单独排查和验证。
怎样保存可复查的结果
我为每批验收保留结构化 JSON,而不是只保存终端中的“通过”字样。结构化结果便于再次统计,也能定位到具体方法、脱敏路径和备注。
整理这份记录时,我只保留:
- 模块分组;
- 用例总数和通过数量;
- 典型问题类型;
- 修复与复测方法;
- 尚未覆盖的边界。
不会公开:
- 实际服务 URL、IP 和端口;
- Token、密码和验证码;
- 测试账号、用户 ID 和资源 ID;
- 请求正文中的真实数据;
- 数据库连接和内部路径;
- 可以用于重放管理操作的参数。
原始明细继续用于项目内部追溯,这份记录不复制全部请求。
115 项通过能说明什么
这轮结果可以确认:在 2026 年 4 月 18 日的单机 Docker Compose 验收环境中,三批共 115 个预设接口用例得到预期结果,认证、用户、内容、评论、推荐和后台管理的主要接口链路能够按这些用例运行。
它不能证明:
- 接口文档中的约 186 条 endpoint 都是独立且全部测试;
- 所有参数组合和边界值都已覆盖;
- 高并发下仍能保持相同结果;
- 多节点故障切换已经通过;
- 消息、缓存、数据库和对象存储始终正常;
- 前端全部交互都已验收;
- 系统已经达到生产环境要求。
这轮验收留下的方法
这次接口验收真正有价值的,不只是 115/115,而是一条可以重复执行的过程:
确定独立用例口径
-> 按模块准备前置数据
-> 同时覆盖成功与拒绝场景
-> 保存结构化结果
-> 根据失败定位运行版本、权限、事务和数据关系
-> 修复后重建环境并复测
-> 区分接口通过与组件健康
-> 记录未覆盖边界接口验收不是把所有状态刷成绿色,而是让每一个“通过”都能说清测试前提、实际结果和证据范围。这样得到的结果,才适合继续用于项目复盘和下一轮验证。