10.3 测试策略与持续集成


10.3 测试策略与持续集成

本节摘要:质量线是交接的压舱石:测试按金字塔分层——服务层单元测试脱离容器跑、集成测试验证数据链路、界面自动化守住关键路径;持续集成把构建、测试、规范墙串成一条自动流水线,让坏代码进不了主干。本站是全书的最后一站:给老站补上第一条流水线,让前面九章攒下的所有纪律获得一个自动执行的宿主。

给老站补第一条流水线

老站普遍没有流水线,因为它"历史上一直人肉部署也没塌"。但人肉部署的成本是隐性的:每次上线靠胆量,每次交接靠运气,规范靠自觉——第 8 章已经论证过,靠自觉的规范必然衰减。流水线的价值因此不在提速,而在把纪律变成机制:构建失败进不了库,测试不过合不了并,规范墙红灯上不了线。

最小可用的流水线只要四环,多一环都是给老站加戏:

环节顺序有讲究:规范墙放在测试之前,让廉价检查先跑(秒级失败反馈,开发者最愿意看);单元测试次之;打包靠后。四环之外,等团队尝到甜头再逐步加集成测试与界面自动化——一次上十环的流水线,红一次就有人想把它关掉。

测试金字塔:从服务层往上

测试分层的原理第 4 章其实已经埋好:分层做得越彻底,能脱离容器测试的代码就越多。金字塔三层各有各的守区。

底层:服务层单元测试,守业务规则。第 4 章立的红线"服务层不依赖容器"在这里兑现红利——订单服务的规则(库存不足抛异常、金额计算、状态流转)全部可以在纯 Java 环境里验证,数据访问换成内存假件:

public class OrderServiceTest { @Test void 库存不足时下单失败且不落单() { OrderDao dao = new FakeOrderDao(); BookDao book = new FakeBookDao(); // 预置库存为零 OrderService service = new OrderService(book, dao); assertThrows(BizException.class, () -> service.place("BOOK-001", "user-42")); assertEquals(0, dao.savedCount()); // 关键:一单都没落 } }

这个测试守的正是 4.3 节事务纪律的业务面:失败时不该有任何写入。老站补测试从服务层起步还有个策略理由——它是历史病灶(安全规则、金额计算)最密集的地方,测试即回归保险,写一个守一个。

中层:集成测试,守数据链路。服务层用假件快而隔离,但查询语句对不对、事务提交回滚是否如预期(4.3 节的压测正是这么来的),必须对真实数据库验证。集成测试跑在流水线里要有专属数据库实例,每个用例自带数据装配与清理,跑完不留痕。

顶层:界面自动化,守关键路径。几百个页面不可能全测,守的应是站点的"生命线":首页能开、搜索能查、下单能成、登录能通。浏览器自动化工具模拟真实点击,每次发布前把生命线跑一遍——页面级回归成本极高,恰恰因为它贵,才只花在最值钱的路径上。

三层合起来看分工:单元测试管"规则对不对",集成测试管"链路通不通",界面自动化管"生命线还在不在"。老站测试的目标从来不是覆盖率数字,是让最重要的行为不至于被悄悄改坏

案例:第一条流水线的上线周

背景:交接周最后一天,流水线要在新同事手上完成接管验收。此前站点只有一台人肉部署的服务器,没有任何自动检查。

操作:按最小四环搭建。声明式构建沿用 10.1 节的配置;规范墙把 8.2 节的三条检查(脚本存量、拼接查询、裸输出)接成构建前置步骤;单元测试套件从服务层起步——先给订单与库存规则补了十四个用例,把安全补课时的注入防护也以测试形式固化(7.1 节的复现脚本反向改写成断言);打包后自动投递预发环境,新同事执行完整验证。

结果:流水线第一次跑就在规范墙拦下一个真实问题——新同事自己上午提交的代码里带了一段临时脚本片段。拦截发生在合入前,纠正只花了两分钟。这次"被自家墙拦住"成了验收日最有说服力的演示。

解读:这条流水线的深层意义是全书纪律的宿主合体:第 3 章的语法清点产出脚本基线、第 7 章的安全红线变成断言、第 8 章的规范墙找到执行点、本章把它们串成机制。翻新十个月攒下的所有"约定",至此全部变成"机器守护的事实"——交接出去的不再是一个靠人盯的站点,而是一个会自我纠错的站点。

变式:如果站点历史包袱太重,单元测试一时铺不开,倒序启动流水线也是正路:先只开构建加规范墙两环(它不要求任何测试基础),红绿稳定后再逐步加测试环。流水线的演进节奏与 8.2 节的规范墙同一条心——增量严格、存量设基线、先活下来再收紧。

💡 关键直觉:整个交接周的终极交付物可以浓缩成一句话——让下一个人比你自己维护它更省力。环境清单降低上手成本,兼容矩阵降低排障成本,流水线降低纪律成本。至此,青梧书肆的故事讲完了:愿你接手的每个老站,都遇上读过本书的前任;愿你交出的每个站点,都对得起本章这句验收词。

测试数据的装配纪律

测试金字塔搭起来后,测试数据是长期运转的燃料,装配纪律决定这套体系能活多久。三条纪律如下。其一,数据随用例装配:每个测试用例自己负责创建它依赖的数据、跑完自己清理,绝不吃别的用例的剩饭——共享数据的测试套件会在并发执行时互相污染,红绿随机,最终没人再信它。其二,敏感数据脱敏进库:集成测试用的数据集若从生产抽样,证件号、手机号、口令一律替换,测试库的安全等级按生产对待——测试库泄密也是泄密。其三,数据构造函数化:把"造一个下单会员""造一本在售图书"这类动作封成工厂方法,用例读起来是业务语言,数据字段变更时只改工厂一处。三条纪律的共同目标是让测试套件在三年后依然好懂好改——测试是给未来维护者的第一份礼物,别送一堆跑不起来的祖传脚本。

流水线的红绿文化

流水线搭好之后,真正的挑战是文化:红灯出现时团队的第一反应,决定了这套体系的寿命。健康的文化只有一条:红灯是礼物,它在你付不起的时机之前拦住了问题。对应的行动守则有三——红灯出现,提交人十分钟内响应(修复或回滚),不过夜;红灯期间主干冻结合入,防止问题叠问题;修复后花五分钟记录原因,一周内同类红灯再出现,就值得把这类检查加强而不是放宽。反面教材是"红灯常态化":红着就红着,大家绕着走,流水线沦为摆设。青梧书肆交接前最后做的一件事,就是把这三条守则贴在流水线的看板页上——机器拦得住代码,拦不住人心,文化那部分得靠反复宣讲。红绿灯都有了,路才算真正修好。

本节要点回顾

  • 流水线四环起步:构建、规范墙、单元测试、打包投递,先让机制跑起来再逐步加密;
  • 金字塔各守一层:单元守规则、集成守链路、界面守生命线,老站补测试从服务层起步;
  • 测试即回归保险:历史病灶密集的服务层优先覆盖,安全复现脚本反向固化为断言;
  • 被自家墙拦住是最好的验收:纪律从"要求别人"变成"约束所有人",规范才算立住;
  • 交接的终极验收:新同事独立完成改代码、过流水线、部署预发的完整循环,全程无需求助。

作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U