“已经能 build 了”是开发里最容易制造错觉的一句话。
构建通过通常说明:依赖能安装、语法和打包链路没有阻断性错误、框架能够产出部署产物。它不保证用户能登录,不保证付款以后权益真的到账,也不保证管理员看不到别人的数据。
产品上线前,需要把不同风险拆成不同验收层。
第一层:静态检查
类型检查、Lint、编译和依赖安装属于这一层。它们便宜、速度快,应该尽早跑。
静态检查很擅长发现类型不一致、无效导入、明显语法问题,却看不到业务语义。例如一个退款接口把金额乘错 100 倍,只要类型还是 number,TypeScript 不会替你报警。
第二层:确定性业务测试
把重要规则做成单元或集成测试。例如积分只能扣一次、匿名用户不能读私有记录、过期订单不能再发货、同一个 webhook 重放不会重复加权益。这些规则越接近钱和权限,越不应该只靠人“点过一次”。
测试的价值不只是上线前。三个月以后改另一处代码时,它能告诉你旧规则有没有被破坏。
第三层:真实依赖链路
Mock 能证明自己的代码按预想调用了一个接口,但不能证明第三方真的接受。
认证回调 URL、支付 webhook、邮件域名、数据库权限、对象存储 CORS、生产环境变量,很多问题只有接到真实或官方 sandbox 才暴露。支付至少要跑 provider 测试环境,OAuth 要走一次完整回调,数据库迁移要在空库和已有数据路径都检查。
第四层:浏览器中的完整任务
接口都正确,页面仍可能坏。按钮被遮住、移动端弹窗超出屏幕、登录以后重定向错、付款成功页面读到旧状态、表单校验和后端规则不一致,都属于真实用户路径的问题。
至少把核心链路从用户入口走到最终结果,按风险覆盖未登录、已登录、失败和重试分支。
第五层:安全和权限
OWASP ASVS 把 Web 应用安全拆成身份、会话、访问控制、输入、API、数据保护等系统性要求。小产品没必要机械追求大型金融系统的全部等级,但“规模小”不是跳过权限边界的理由。
最基本的问题包括:服务端是否重新验证身份;用户能否改 URL 读到别人的对象;敏感接口是否依赖浏览器传来的角色;密钥有没有进入客户端包;预览环境会不会被搜索引擎收录。
第六层:生产环境冒烟
部署成功以后再做一次最小验证:打开真实域名、确认 HTTPS 和重定向、检查首页与核心接口、跑一条不会破坏真实数据的用户路径、观察日志和错误监控。
验收不是测试越多越好。页面文案错一个字可以上线后改;重复扣款、越权读取和数据迁移错误必须在前面拦住。
把风险分层以后,“能上线”不再是一个模糊感觉,而是一串证据。Build 只是第一张。