03_测试CI与部署
单元到端到端测试、CI 流水线、配置、部署、可观测性与回滚。
测试、CI 与部署
学习目标:把代码从“本地可运行”推进到“可重复验证、可观察、可回滚”。
1. 测试按风险分层
| 层次 | 验证重点 | 典型速度 |
|---|---|---|
| 单元测试 | 业务规则、边界值 | 快 |
| 集成测试 | 数据库、缓存、外部适配层 | 中 |
| 契约/API 测试 | 状态码、字段、权限 | 中 |
| 端到端测试 | 关键用户流程 | 慢 |
不要只追求覆盖率数字。优先测试最贵的失败:重复创建、越权、事务部分成功、迁移不兼容和服务重启后的数据保留。前端与后端应共用一份 API 契约;接口变化先检查双端兼容性。
2. 最小 CI 流水线
拉取代码 → 安装固定版本依赖 → 格式/静态检查 → 单元测试
→ 数据库集成测试 → 构建产物 → 安全扫描 → 发布候选
CI 运行在干净环境,不能依赖本机缓存或未提交配置。测试密钥与生产密钥分离;不要在日志输出凭证。构建产物应可追溯到提交与依赖版本。
3. 配置、部署与回滚
配置与代码分离:数据库 URL、密钥、外部服务地址由环境或密钥管理提供。部署前备份与迁移数据库;应用先兼容旧表结构,避免滚动发布时新旧实例互相破坏。发布失败时能恢复上一个应用版本,数据库回滚往往更难,应提前设计兼容迁移。
容器镜像应尽量小、固定基础镜像版本、使用非 root 用户并只包含运行所需文件。反向代理或平台层提供 TLS;服务设置健康检查、资源限制和优雅退出。
4. 可观测性与故障排查
- 日志:结构化记录请求 ID、错误类型与必要上下文,不记录密钥和完整敏感数据。
- 指标:请求量、错误率、延迟分位数、数据库连接池、队列积压。
- 追踪:跨前端、API、数据库或外部服务定位慢调用。
- 告警:针对用户可感知的问题和持续异常,而非每条日志都报警。
自测
- 为什么数据库迁移要考虑新旧应用短时间共存?滚动发布时两种版本可能同时处理请求。
- CI 测试通过是否等于线上一定没问题?不等于,还需发布观察、告警与回滚方案。
5. 让每一层测试承担不同证据
单元测试验证标题规范化、权限判定、版本冲突等纯规则;数据库集成测试验证约束、事务和迁移;API 测试验证请求解析、状态码和错误结构;端到端测试验证浏览器登录、创建、刷新后仍可见。不要让所有测试依赖同一个真实外部服务,否则失败难定位且运行慢。
为笔记服务建立一张验收表:正常创建、空标题、同键重复提交、用户 A 读用户 B 数据、版本冲突、数据库不可用。每个场景至少有一层直接验证,越权和事务回滚需要真实边界的测试,不能只 mock 掉。
6. CI 的可复现标准
每个作业从声明的运行时版本和锁定依赖开始,明确数据库服务、迁移命令与测试命令。缓存只能加速,清掉缓存后仍应通过。构建产物标记提交 ID;若测试与构建使用不同依赖版本,测试通过并不能证明发布产物可靠。
检查格式与类型 → 单元测试 → 启动测试数据库并迁移
→ API/集成测试 → 前端构建与组件测试 → 关键 E2E
→ 生成可追溯产物 → 人工或自动发布门禁
7. 发布后验证与回滚演练
发布前记录当前版本、备份状态、迁移脚本和回滚方式;发布后用真实健康检查和一条只用测试账户的关键流程验证。观察错误率、P95 延迟、数据库连接池和前端请求失败率。若异常超阈值,先回滚应用版本,再评估数据库数据是否需要修复;破坏性迁移往往无法简单回滚,应采用先兼容、后切换、最后清理的顺序。
练习:故意让新版本读取不存在的字段,验证 CI 或预发能否发现;再演练恢复旧应用,同时说明为什么旧应用仍应兼容迁移后的表结构。