LabHub
学习 学习路径 课程

CI/CD 流水线

门禁这件事,就是定下「拦什么」的标准

在 LabHub 中继续学习

一句话总结

测试门的本质不是频繁进行测试,而是事先商定在出现某种信号时如何阻止合并,并让机器代替做出判断。

##为什么需要这个

缺陷越晚发现越贵。IBM研究被广泛引用的水分损失开发阶段1、QA10、生产100以上。即使是相同的错误,在我的分支中发现的话30分钟就能结束,但在生产中发现的话,除了故障应对、热修复、反思、客户沟通外还会附加费用。门是试图在成本曲线左端发现的装置。

问题在于要做多少测试。测试金字塔的推荐比例是单位70/综合20/E2E10。如果变成倒置的反金字塔(冰淇淋棒),四个都会同时出现。E2E会变慢,反馈循环变长,玩家频繁,即使失败也很难找出原因,维护成本也会成指数级增长。测试变多了,但没有人相信结果的状态就是这样的。

概念图: 太慢 · 只支付变更的部分。 · 分阶段进行。 · 并行运行。

怎么操作

大门分为三个部分。

第一,评判标准。覆盖率的目标是核心业务逻辑80%以上,总共60~80%,但不能忘记,比起100%覆盖率,具有有意义的assertion的测试更重要的原则。只按数字来做的测试只会让覆盖率报告看起来漂亮,而错误则会原封不动地通过。

第二,阻止策略。必须阻止与单元的整合。E2E只阻止主要流,其余留作观察。性能只有在超过临界值时才会阻止,安全扫描只阻止CRITICAL。混沌测试保持非阻止状态,只观察指标。全部阻止的话,人们会先学会绕过门槛的方法。

第三,强制分支。实际强制门禁的地方不是管道脚本,而是分支保护的required status checks。脚本只生成结果,阻止合并的权限由仓库设置提供。IaC方面也有同样的做法。Plan在PR中显示,Apply在merge后自动执行。

Playkey测试是吞噬门的信任的幕后黑手,需要单独处理。使用等待特定条件的显式等待,而不是固定的sleep,断开测试之间的依赖性,用 Mocking 或有限重试来包围网络,将日期等动态数据固定。重试必须有上限。无限重试不是稳定化,而是掩盖失败。即便如此,摇摆不定的测试也要放入隔离列表,防止合并,但要留下隔离的事实在报告中,以免被遗忘。

在现场相遇的样子

第一次打开大门时,一定会收到“现在很着急,因为这个原因不能出去”的请求。这时需要的不是例外批准程序,而是关闭大门的开关。另一个经常看到的场景是,为了修复失败的测试,而增加重试次数。虽然重试次数增加,但如果失败率保持不变,那么该测试已经不是信号,而是噪音。

要快才能守住大门

人们绕过闸口的最大原因不是因为规则严格,而是太慢。如果要等40分钟才能合并,开发者就会把小变化收集成一大块,一大块很难进行评论,也很难撤销。从闸口的目的是完全相反的角度来看,这不仅仅是简单的不便,而是设计失败。

获得速度的方法是确定的。

也不要忘记计时。**记录管道各阶段所需的时间,如果有一天突然变慢,就可以找到原因。**如果没有这个记录,只会重复“最近CI变慢了”,没有人能回答从什么时候开始变慢。

最后,决定门的成败的一个文化条件是不要忽视红色管道。如果main被破坏了一天,后面出现的任何更改都无法知道是自己的错还是不是,门作为信号的功能就会完全丧失。需要达成一致,如果被破坏了,修复或恢复比其他任何工作都优先。因为恢复几乎总是最快的,所以即使还不清楚原因,先恢复main为绿色并调查也是正规做法。

##下次实习要做的事情

直接用Shell制作测试跑者和覆盖门、重试、隔离。即使失败也让跑者把剩下的全部回转到最后,展示整个画面。覆盖门在界限值上准确判断,有上限的重试,以及制作出数值和判断一致的JSON报告。