第1章 CI/CD基础与集成测试概述
说到CI/CD和集成测试,我做了快十年 DevOps,踩过的坑比吃过的盐还多。你想想看,一个项目从代码提交到上线,中间要经过多少道坎?如果连集成测试这关都过不了,后面全是瞎忙活。
说白了,CI/CD 就是让机器帮你干活——自动拉代码、自动构建、自动跑测试。集成测试呢,就是验证你的新代码跟现有系统能不能好好过日子。我见过太多人把单元测试跑绿了就认为万事大吉,结果一合并就炸。
三大主流工具,到底选哪个?
目前在业界主流的 CI/CD 工具就三把:GitLab CI、Jenkins、GitHub Actions。我每个都用烂了,给你说说真实感受。
| 对比维度 | GitLab CI | Jenkins | GitHub Actions |
|---|---|---|---|
| 配置方式 | .gitlab-ci.yml 声明式,简洁 |
GUI 配置 + Jenkinsfile (Groovy) | .github/workflows/*.yml 声明式 |
| 部署模式 | SaaS 或自托管 Runner | 自托管为主,功能全面 | SaaS 为主,也支持自托管 |
| 适用场景 | GitLab 全家桶用户;中小团队 | 复杂流水线;大型企业;重度自定义 | GitHub 生态;开源项目;快速启动 |
| 核心优势 | 内置 CI/CD,零运维成本 | 插件生态强大,几乎无所不能 | 与代码仓库深度绑定,社区市场活跃 |
| 避坑点 | 高级功能收费, Runner 资源有限 | 维护成本高,新手容易配出“屎山” | 免费额度有限,调试日志只有 7 天 |
别不信,选错工具真的会死人。 我有个朋友的公司,老板听销售忽悠上了 Jenkins,结果光搭集群就折腾了两周,之后每次更新插件都要停服务。他私下跟我说:早知道用 GitLab CI,代码一推就完事了。
GitLab CI:小团队的真香之选
如果你公司用 GitLab 管理代码,直接用它的 CI 是最省心的。我前两年带一个 20 人的团队,从 Jenkins 迁移到 GitLab CI,流水线配置量直接砍掉 60%。
配置很简单,一个 .gitlab-ci.yml 文件搞定。比如最基础的流水线:
stages:
- build
- test
- deploy
build-job:
stage: build
script:
- mvn clean package
test-job:
stage: test
script:
- mvn test
嗯,就这么几行,自动触发构建和测试。集成测试阶段通常放在 test 阶段之后,你可以加个 stage 专门跑:
integration-test-job:
stage: integration-test
script:
- docker-compose up -d
- mvn verify
- docker-compose down
我习惯把集成测试环境用 Docker Compose 管理,跑完自动销毁,不占地方。
小技巧: 在 .gitlab-ci.yml 里用 only 和 except 控制触发条件,避免每次 commit 都跑一遍完整集成测试。
Jenkins:大而全,但请善待你的运维
Jenkins 出道早,插件多到能铺满一个足球场。但说实话,现在新项目我基本不推荐它了——除非你们公司有专职的 CI/CD 运维团队。
Jenkins 的流水线有两种写法:声明式和脚本式。我更喜欢脚本式的 Jenkinsfile,灵活性高:
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'mvn clean package'
}
}
stage('Integration Test') {
steps {
sh 'docker-compose up -d'
sh 'mvn verify'
sh 'docker-compose down'
}
}
stage('Deploy') {
steps {
sh 'scp target/*.war deploy@server:/opt/tomcat/webapps/'
}
}
}
post {
always {
junit '**/target/surefire-reports/*.xml'
}
}
}
我曾经遇到过 Jenkins 的 Master 节点内存泄漏,排查了整整两天才发现是某个插件版本不兼容。你想想看,如果 Jenkins 崩了,所有构建都停了,那酸爽。
注意: Jenkins 的插件安全漏洞层出不穷,记得定期更新并备份 JENKINS_HOME。我用过一个叫 "Build Timeout" 的插件后来被爆严重漏洞,被迫紧急升级。
GitHub Actions:开源项目的最佳拍档
如果你的代码在 GitHub 上,又不想自己搭服务器,GitHub Actions 是最省事的。免费额度对于个人项目和中小公司完全够了,每小时 2000 分钟,还支持 Linux/macOS/Windows。
配置文件和 GitLab CI 很像,也是 YAML 格式。比如这样一个工作流:
name: CI Pipeline
on:
push:
branches: [ main ]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
- name: Build and Integration Test
run: |
docker-compose up -d
mvn verify
docker-compose down
它最方便的是可以直接复用社区写好的 Action,比如数据库、缓存服务,一行 uses 就搞定。我帮一个客户做项目时,用 GitHub Actions 跑集成测试,从零到上线只花了一个下午。
集成测试到底该在哪跑?
很多新手把集成测试和单元测试放在同一个阶段。我明确告诉你:不要这么做。单元测试应该跑得飞快(秒级),集成测试通常需要启动外部服务(分钟级)。混在一起会让反馈变得很慢。
正确做法是分阶段——单元测试先跑,失败了就立刻终止,然后才跑集成测试。你可以用流水线中的 when: on_success 控制。这样开发人员提交代码后,5 秒内收到单元测试结果,如果过了再等几分钟跑集成测试,心理压力小很多。
避坑指南: 我曾经把集成测试的数据库配置写死了,导致每次 CI 都要连生产环境的测试库,差点把线上数据冲掉。后来我要求所有集成测试都必须在独立容器里跑,用完就删,绝不混用环境。
选型怎么做?我给你的真心建议
直接给结论吧,方便你抄作业:
- 如果你用 GitLab 管理代码,且团队小于 50 人 —— 无脑选 GitLab CI。不需要运维,Pipeline 配置简单。
- 如果你们是大型企业,有专职 DevOps,需要对接一堆老旧系统 —— 选 Jenkins。但要做好心理准备,维护 Jenkins 就像养了个祖宗,每周都得伺候。
- 如果你是独立开发者、开源项目,或者公司代码全在 GitHub —— 选 GitHub Actions。免费额度足够用,社区 Action 让你少写很多代码。
- 集成测试环境一定要容器化 —— 不管用哪个工具,都把依赖的服务(数据库、消息队列、缓存)用 Docker 跑起来。我见过太多人因为环境不一致,本地跑绿了,CI 上就红。
最后提醒一句: 别为了炫技而选工具。我见过有团队把 Jenkins Pipeline 写得无比复杂,结果出了问题没人敢动。简单、可维护,比什么都重要。