基于Gitlab实现自动化单元测试

持续集成是一种软件开发实践,每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误,大大减少集成的问题,让团队能够更快的开发内聚的软件。

实现目标

单元测试作为持续集成的一部分,下面我们借助gitlab的CI能力来实现以下目标:

  • 每个开发人员在各自开发分支开发,每当提交代码后自动触发单元测试
  • 开发完成后由开发人员发起merge request并触发单元测试,如果单元测试不通过则不允许合并
  • 如果单元测试通过并code review后没问题则允许代码合并

实验环境:

php:7.4
phpunit: 9.5.9
gitlab: 14.2.4-ee

创建Gitlab项目及单元测试代码准备

在gitlab上创建一个cicd-php的PHP代码用于测试


image.png

单元测试具体如何编写可参考文章: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 : 假设为要测试的业务逻辑,以下写了一个简单的加法函数用于测试

<?php
namespace App\Service;

class MyLogic
{
    public function add($num1, $num2)
    {
        return $num1 + $num2;
    }
}

test/unit/MyLogicTest.php : 为MyLogic类的单元测试

<?php
namespace Test\unit\Service;

use App\Service\MyLogic;
use PHPUnit\Framework\TestCase;

class MyLogicTest extends TestCase
{
    public function testAdd()
    {
        $logic = new MyLogic();
        $ret   = $logic->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.png

安装Gitlab-runner并注册

  • 安装docker
$ yum install docker
  • 安装gitlab-runner

可以从gitlab上获取runner所需的URL和注册token,路径为Settings > CI/CD > Runners settings


image.png
#拉取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


image.png

注:如果宿主机没有开启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任务进行自动化构建


image.png

pending:表示任务执行中
failed:表示任务执行失败
passed:表示任务执行成功

image.png
image.png

以下我们新建一个test分支,并将MyLogicTest的断言改为失败的断言,来测试test分支merge_request到main分支,单测失败的场景

<?php

namespace Test\unit\Service;

use App\Service\MyLogic;
use PHPUnit\Framework\TestCase;

class MyLogicTest extends TestCase
{
    public function testAdd()
    {
        $logic = new MyLogic();
        $ret   = $logic->add(1, 1);
        $this->assertSame($ret, 3);
    }
}

在gitlab发起merge request


image.png
image.png

创建merge request后会自动触发一个pipeline进行构建


image.png

如果pipeline执行失败会显示一个红色的x


image.png

接下来我们在test分支将单元测试断言修改为正确并提交,会发现原来的merge request的状态重新变为执行中,点击“merge when pipeline succeeds”则表示当pipeline执行成功后则自动合并代码

image.png

当pipeline执行成功后,则表示该merge request的代码已经通过了单元测试,点击“Merge”按钮就可以将分支代码合并到目标分支


image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352

推荐阅读更多精彩内容