CI流水线设计:阶段划分、触发器与并行策略

做冒烟测试这几年,我最大的感触就是——流水线设计决定了整个CI的命。你想想看,如果流水线阶段没划好,触发器乱设,并行串行一团糟,那冒烟测试跑得再快也白搭。今天我就把这三块核心内容掰开揉碎了讲,结合我踩过的坑,争取让你看完就能用。

流水线阶段划分:别把鸡蛋放一个篮子里

阶段划分,说白了就是让流水线像生产流水线一样,每个工位只干一件事。我个人习惯把CI流水线分成这几个阶段:

  • 代码检查阶段:静态分析、lint、格式化检查
  • 构建阶段:编译、打包、生成制品
  • 冒烟测试阶段:快速验证核心功能是否可用
  • 单元测试阶段:细粒度测试,覆盖逻辑分支
  • 集成测试阶段:多服务联调
  • 部署/发布阶段:推送到测试环境或制品仓库

我在项目中遇到过团队把所有测试塞进一个阶段的情况,结果一次提交跑了40分钟才报错。后来拆成冒烟+单元+集成三层,冒烟5分钟内就能给反馈,爽多了。

关键原则:每个阶段只做一件事,前一阶段失败立即终止后续阶段。这叫 Fail Fast。

触发器设置:什么时候该动,什么时候该歇

触发器就是流水线的开关阀。设置不对,要么浪费资源,要么漏掉关键事件。我常用的触发器类型:

触发器类型 适用场景 我的建议
Push 触发 任何分支推送到远程 只对 feature 分支做快速冒烟,别跑全套
Pull Request 触发 PR 创建/更新 跑完整流水线,这是合码前的最后防线
定时触发 夜间全量回归 别放高频,一周一次足矣
手动触发 紧急修复、重跑失败任务 保留,但不要当成日常流程

嗯,这里要注意一个坑。我曾经把 Push 触发直接配上了全量流水线,结果开发者每次 git push 都要等30分钟才能继续工作。后来改成 Push 只跑冒烟测试 + 代码检查,PR 才跑全量,效率直接翻倍。

技巧:用路径过滤+分支模式来控制触发器粒度。比如 src/** 的变更才触发,文档变更直接跳过。

并行与串行策略:既要快,又要稳

这个问题,很多人上来就追求全部并行。其实不对。你想想看,如果冒烟测试还没过,就并行去跑集成测试,那不是浪费资源吗?我个人习惯这样配:

  • 串行确保依赖链:冒烟→单元→集成→部署,每个阶段必须等前一个完全成功后才能开始。
  • 并行提高吞吐:在同一阶段内,各测试任务可以并行跑。比如冒烟测试里的10个场景,拆成10个并行 job 跑。
  • 混合策略:阶段间串行,阶段内并行。这是最实用的。
# 示例:Jenkins Pipeline 片段
stage('冒烟测试') {
    parallel {
        stage('API冒烟') { ... }
        stage('UI冒烟') { ... }
        stage('核心流程冒烟') { ... }
    }
}
stage('单元测试') {
    // 等冒烟全部通过才执行
    ...
}

我曾经遇到一个项目,把冒烟测试直接串行跑完所有场景,每次20分钟。后来改成分组并行,5分钟搞定。差别就这么大。

警告:并行不是越多越好。一个流水线同时起30个 agent,结果资源耗尽,所有任务争 CPU,反而更慢。建议根据团队机器负载动态控制并发数。

核心知识体系总览

CI流水线设计核心逻辑 CI流水线设计:阶段·触发器·并行策略 流水线设计三要素 阶段划分 触发器设置 并行/串行策略 代码检查 构建 冒烟测试 单元测试 集成测试 部署 Push 触发 PR 触发 定时/手动触发 阶段间串行 阶段内并行 Fail Fast 控制并发数 串行为保稳,并行为提效,触发器做开关——三者缺一不可

实战案例:一次失败的流水线重构教训

我记得有个项目,团队把“并行”做到了极致——所有阶段全部并行,连构建和测试都同时跑。结果呢?构建还没完成,测试就开始拉旧版本制品,测试结果全是假阳性。这是典型的依赖关系没理清。

后来我帮他们改成这样的结构:

  1. 构建+代码检查:串行(先检查后编译)
  2. 冒烟测试:并行跑3个快速场景
  3. 单元测试:按模块分4组并行
  4. 集成测试:串行等待环境准备好
  5. 部署:手动确认后触发

这个调整让平均流水线耗时从35分钟降到了12分钟,而且再也没有出现“构建未完成就测试”的乌龙。

核心总结:

  • 阶段划分要遵循“单一职责”,别混在一起
  • 触发器要区分“快速反馈”和“完整验证”,别一刀切
  • 并行串行的核心逻辑是:串行保依赖,并行保效率