持续集成是一种软件开发实践,每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误,大大减少集成的问题,让团队能够更快的开发内聚的软件。
实现目标
单元测试作为持续集成的一部分,下面我们借助gitlab的CI能力来实现以下目标:
- 每个开发人员在各自开发分支开发,每当提交代码后自动触发单元测试
- 开发完成后由开发人员发起merge request并触发单元测试,如果单元测试不通过则不允许合并
- 如果单元测试通过并code review后没问题则允许代码合并
实验环境:
php:7.4
phpunit: 9.5.9
gitlab: 14.2.4-ee
创建Gitlab项目及单元测试代码准备
在gitlab上创建一个cicd-php的PHP代码用于测试
单元测试具体如何编写可参考文章:PHP单元测试基础实践(PHPUnit)
在此项目中我们利用composer安装了phpunit来对PHP的代码进行单元测试,安装完成后在项目根目录的vendor/bin/目录会出现phpunit的可执行文件
$ composer require --dev phpunit/phpunit
项目目录结构如下:
├── app
│ └── Service
│ └── MyLogic.php
├── test
│ ├── bootstrap.php
│ └── unit
│ └── MyLogicTest.php
├── composer.json
├── composer.lock
├── phpunit.xml
└── vendor
app/Service/MyLogic.php : 假设为要测试的业务逻辑,以下写了一个简单的加法函数用于测试
test/unit/MyLogicTest.php : 为MyLogic类的单元测试
add(1, 1);
$this->assertSame($ret, 2);
}
}
通过执行phpunit执行单元测试,通过以下输出可看出执行了一个单元测试并且执行成功
$ ./vendor/bin/phpunit -c ./phpunit.xml
PHPUnit 9.5.9 by Sebastian Bergmann and contributors.
. 1 / 1 (100%)
Time: 00:00.009, Memory: 6.00 MB
OK (1 test, 1 assertion)
配置Gitlab-CI功能 及 Gitlab-runner
GitLab-CI:就是一套配合GitLab使用的持续集成系统
GitLab-Runner:是配合GitLab-CI进行使用的。用来自动化执行软件集成脚本的进程。当这个工程的仓库代码发生变动时,比如有人push了代码,GitLab就会将这个变动通知GitLab-CI。这时GitLab-CI会找出与这个工程相关联的Runner,并通知这些Runner把代码更新到本地并执行预定义好的执行脚本。
Runner就像一个个的工人,而GitLab-CI就是这些工人的一个管理中心,所有工人都要在GitLab-CI里面登记注册,并且表明自己是为哪个工程服务的。当相应的工程发生变化时,GitLab-CI就会通知相应的工人执行软件集成脚本。
安装Gitlab-runner并注册
- 安装docker
$ yum install docker
- 安装gitlab-runner
可以从gitlab上获取runner所需的URL和注册token,路径为Settings > CI/CD > Runners settings
#拉取gitlab-runner镜像
$ docker pull gitlab/gitlab-runner
#启动gitlab-runner
$ docker run -d --name gitlab-runner --restart always \
-v /srv/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
--network=host \
docker.io/gitlab/gitlab-runner
# 进去容器
$ docker exec -it gitlab-runner bash
# 执行注册gitlab-runner命令,此处按提示输入相关的参数即可
$ gitlab-runner register
注册后在gitlab可以看到runner
注:如果宿主机没有开启ipv4转发,那么docker的bridge网络将不能访问外网,开启ipv4转可参考以下步骤
#配置转发
$ vim /etc/sysctl.conf
net.ipv4.ip_forward=1
# 重启网络
$ systemctl restart network
#查看是否成功,以下命令如果返回1则表示成功
$ sysctl net.ipv4.ip_forward
配置Gitlab-CI配置文件
为了利用gitlab的持续集成能力,我们可以通过在项目根目录写一个.gitlab-ci.yml配置文件来开启gitlab pipeline功能
stages:
- test
job1:
stage: test
tags:
- cicd
only:
- main
- merge_requests
script:
- ./vendor/bin/phpunit -c ./phpunit.xml
注:merge_requests 的功能在gitlab 11.6之后的版本才支持
每当main分支提交代码时,并会触发一个pipeline任务进行自动化构建
pending:表示任务执行中
failed:表示任务执行失败
passed:表示任务执行成功
以下我们新建一个test分支,并将MyLogicTest的断言改为失败的断言,来测试test分支merge_request到main分支,单测失败的场景
add(1, 1);
$this->assertSame($ret, 3);
}
}
在gitlab发起merge request
创建merge request后会自动触发一个pipeline进行构建
如果pipeline执行失败会显示一个红色的x
接下来我们在test分支将单元测试断言修改为正确并提交,会发现原来的merge request的状态重新变为执行中,点击“merge when pipeline succeeds”则表示当pipeline执行成功后则自动合并代码
当pipeline执行成功后,则表示该merge request的代码已经通过了单元测试,点击“Merge”按钮就可以将分支代码合并到目标分支