Gitlab-CI 入門實作教學 - 單元測試篇

Nick
8 min readSep 13, 2019

--

以實務為例,帶領大家一步步學習 Gitlab-ci 上各種關鍵字的用法

本篇源自工作上月會分享教學文:近期因著公司內部撰寫單元測試風氣越來越盛行,引起自己再次研究如何在 Gitlab 上設定 CI 自動化測試,將自動化測試及部署更全面的加入到開發流程中。

而為求表答清晰及篇文預計會分為三篇文章針對不同情境來切割,將有:

  1. Gitlab-CI 自動化測試 (單元測試入門篇)✔ 本篇
  2. Gitlab-CI 自動化部屬部署
  3. Gitlab-CI 開發流程細節、整合測試、測試報表

此篇閱讀時間約為 5 分鐘,實作 30分鐘。

gitlab ci/cd 執行開發流程,圖片來源

本篇適合對象

  1. 有撰寫測試程式,卻曾沒注意測試未成功就上線的你
  2. 對 CI/CD 有了解,卻遲遲不知道如何下手的你

本篇實作三個重點

  1. 簡介 Gitlab-ci 及 Gitlab runner 關係
  2. 如何在每次上傳版本到 Gitlab 後,都自動執行單元測試
  3. 如何確保每次 Merge Request ,都要通過測試

介紹 Gitlab Runner 及 Gitlab-CI

Gitlab Runner

實際上是一個 docker 的 image,在 Gitlab CI/CD 中每一個工作 (Job) 都是在此運行的,優點是可以確保每次執行的環境都是乾淨的,且可以讓多個工作同時進行,比如執行多種測試項目就可以啟用不同的 runner 同步進行。

Gitlab-CI

會在專案資料夾中偵測到 Gitlab-ci.yml 這個設定檔的時候觸發,主要是負責協調在各種不同情境時 Runner 該啟動是否該啟用及先後順序,比如流程是先測試後部署,就會限制是測試成功後才能部屬,不成功則中斷。

Gitlab CI/CD 實際執行流程,圖片來源

自動化測試流程簡介

如上圖說明,一般來說 CI 會在每次上傳程式到 Gitlab 的時候觸發,負責管理的 Gitlab-CI 會依照 Gtialb-ci.yml 設定檔案來啟用 Runner,而 Runner 執行完結果後再回傳到 Gitlab 進行總結。

終於來到 自動化測試 的範例

建立一個 Laravel 專案並確定能成功啟用

照著 Laravel官方文件Laravel道場翻譯文件 初始部分建立專案,注意需先在環境安裝好 php 及 composer。

// 安裝 laravel 專案 
composer create-project --prefer-dist laravel/laravel learn-cicd
// 移至專案資料夾
cd learn-cicd
// 安裝套件
composer install
// 啟動伺服器
php artisan serve

完成後可在平台上看到預設的專案首頁,如以下

開啟 127.0.0.1:8000 可看到 Laravel 啟用畫面

建置 Unit Test(單元測試)環境

先在本地電腦執行確認可以執行單元測試,因專案預設就會有一個單元測試存放在 tests/Unit/ExampleTest ,直接運行應該會是通過的畫面

// 再次確認安裝測試環境
composer install --prefer-dist --no-ansi --no-interaction --no-progress --no-scripts
// 執行單元測試
./vendor/bin/phpunit --testsuit Unit
本地執行單元測試成功,預設測試範例 ./tests/Unit/ExampleTest

上傳含有 Unit Test 專案到 Gitlab 專案上

  1. 建立 Gitlab 帳號,並建一個專案
  2. 設定本地專案與 Gitlab 位置做連接,複製專案 repo連結
  3. 將本地專案 push 到 Gitlab 上
1. 建立 gitlab 專案
2. 複製 Gitlab 遠端連結
git remote add origin https://gitlab.com/Nick0603/learn-cicd.git
git push origin master

重點二:在 Gitlab 上呼叫 Runner 執行單元測試

建立 Gitlab-ci.yml 設定檔

在專案根目錄(最外層資料夾)中建立 Gitlab-ci.yml 設定檔,當上傳的專案程式中有此設定檔,Gitlab-ci 會讀取後依照內容啟用 Runner 執行工作。

做很久的說明圖

Image 關鍵字
因執行 CI/CD 需要先有如 php、composer、npm的等工具,有這些管理套件工具其實就可以動態再去延伸安裝各種套件了,但如果一開始沒有這些套裝工具,就麻煩了,一個作法是連線到 Runner 環境中逐項安裝,但為了實作方便可以使用 image 這個關鍵字,可以讓 Runner 中切換另個環境去執行工作 (Job),這裡使用 lorisleiva 的 laravel-docker image,其中就已經安裝好上述的工具了。

Job 定義
除了像 image 等等等這些 gitlab-ci.yml 上的關鍵字,其他寫在首行的名字都會被視為是一個 Job 的名字,如範例中的 unit_test 這個就會被視為一個 Job。

Job 內容 - scripts 關鍵字
腳本 (scripts) 就是 Job 的實際內容,執行的指令以 - 符號分行撰寫並且依序的執行,這邊範例是要執行 phpunit 這個單元測試,就如同在本機上要先使用 composer 安裝所有可能所需的套件,再執行 phpunit 。

將含有 gitlab-ci.yml 的專案上傳到 Gitlab

git commit -a -m "add gitlab-ci.yml to run unit_test"
git push origin master
回到 Gitlab 左側點選 CI/CD ,發現 Runner 已經啟動在執行單元測試的檢測了
可依序看到 Runner 啟動後切換了環境並切到單程版本,接著執行腳本的單元測試

重點三:設定要通過測試分支才能進行 Merge

如果有寫測試的人,一定會每次上線的程式都是經過測試成功的,而如何確保這件理所當然的事理所當然的發生了,就靠這個設定了。

Setting >> General >> Merge checks >> Pipelines must succeed

此設定能確保每次的 Merge Reuqest 都是在 CI Testing 當版本的測試單元都成功的情況下才能被 Merge 的,以下就來測試看看不通過的情況吧。

實際看看是否如期阻擋測試未成功的情況

模擬在開發新功時建立新分支 feature-new

git checkout -b "feature-new"

新增錯誤的測試單元
檔案路徑:/tests/Unit/ExampleTest.php

並執行看看測試是否真的有錯誤

因測試單元判斷 2 與 1 不相同,所以測試錯誤

將此錯誤開發上傳至 Gitlab 並發 Merge Request 看看會有什麼結果

git commit -a -m "test will fail in CI pipeline"
git push origin feature-new
模擬要上線情境,點擊左側 Merge Requests 建立送出MR
因有設定如果 CI 中的未成功,會導致 branch 不能被 merge

預告

此系列為工作分享,Gitab-CI 篇預計至少還會有兩篇,下一篇將會講
Gitlab CD (自動化部屬)的部分,重點會有

  • 如何在測試成功後進行 CD 到伺服器上
  • 如何限制只有在 master 分支才能進行部署設定
  • 如何依照開發流程調整需在 staging 人工二次測試後才能上線

結論

此為 Gitlab-CI 分享的第一篇,當時規劃的時一直反覆修改很多次,怕單篇會不會太長、太省略讓入門的人看不懂、又怕講述太繁複 > <,希望你能給我點 feedback 或拍手支持一下,說不定下一篇會早一點出來,哈哈哈。

如果喜歡我這篇文,可以幫我拍手 1-10 下
如果覺得這文章對你有幫助,可以幫我拍手 10–30
如果覺得想看到更多關於學習筆記的文章,可以幫我拍手 30–50
讓我知道也記得 Follow我 陳建宇
更歡迎你在下方留言,我很樂意與你討論聊天或回答問題!

--

--

Nick
Nick

Written by Nick

嗨 我是 Nick,目前在 ShopBack 擔任軟體工程師,喜歡用科技解決問題,偶爾會整理一些工作上的發現分享在這,歡迎大家追蹤及交流