CI/CD Pipeline 之 stage: test

本系列文是從 iT 邦幫忙鐵人賽系列文章搬至 gitlab-book.tw,鐵人賽撰文時 GitLab 仍為 12.x 版本,因此本系列文內容已有部分過期,本次搬移至此後,會視狀況新增一些補註說明。

本系列文是從 iT 邦幫忙鐵人賽系列文章搬至 gitlab-book.tw,鐵人賽撰文時 GitLab 仍為 12.x 版本,因此本系列文內容已有部分過期,本次搬移至此後,會視狀況新增一些補註說明。 鐵人賽原文網址:https://ithelp.ithome.com.tw/articles/10221324

開始今天的進度之前,再幫大家恢復一下記憶,目前規劃的 CI/CD Pipeline 將如下圖。


(這是 dev 與 stg 環境的 CI Pipeline。)

按著我們的規劃,昨天我們已順利將程式部署至目標 Server,今天則要搞定 CI Pipeline 的 Stage: test,也就是在目標 Server 上執行自動化測試。

Stage: test

首先我們要先問在 Stage: test 應該要做些什麼?不過這個問題可就是一個大哉問了,因為「自動化測試」(或測試自動化) 雖然才五個中文字,但也是一個足以寫上鐵人 30 天的關鍵字,不信的話讓我們先看一下著名的測試自動化金字塔。


(測試自動化金字塔 Test Automation Pyramind,網路上可以 Google 到許多討論。)

從上圖就可以該略得知,針對 UI、Service、Unit 自動化測試可以討論的內容非常多。例如最上層的「Automated GUI Tests」,大家就會討論如何使用 Selenium、Appium 或 Robot Framework 之類工具運用面的問題。或者針對自動化測試大家也會討論怎麼管理測試案例、怎麼處理日積月累的眾多自動化測試案例、怎麼加速自動化測試、如何做到測試分級⋯⋯。

自動化測試是 CI/CD 的重要議題,畢竟如果你沒有做自動化測試,就不要跟別人說你有在做 Continuous Integration (持續整合),並不是有了 CI Server 或 CI Pipeline 就等於你已經實踐了 Continuous Integration,而是你的團隊遵守 Continuous Integration 的準則,並透過自動化測試與 CI Pipeline 確實保護了程式的品質,才算是實踐了 Continuous Integration。不過因為本系列文不是「自動化測試 30 天」所以這裡就不繼續深入探討它了,讓我們回到我們的假想情境。

在我們的假想情景中,在 stage: test 我們的 GitLab Runner 將會在目標 Server 上執行自動化測試,因此需要克服的問題是:

  1. 讓 GitLab Runner 具備與目標 Server 溝通的能力或應該說是操控目標 Server 的能力。
  2. 讓目標 Server 具備執行自動化測試案例的能力。

如果你已經搞定昨天的進度 deploy,以及其中的各種麻煩事,那麼應該會覺得上面這兩個問題並不困難。第一項昨天已經用 Ansible 克服了,而第二項屬於事前作業,需要配合你實際要跑哪些自動化測試案例而事先準備。因此延續昨天採用 Ansible 的作法,我們的 .gitlab-ci.yml 可能會變成下面的模樣:

compile:
  stage: build
  tags:
    - "build"
  script:
    - ./configure
    - make
  artifacts:
    paths:
      - bin/compiled-code

deploy-for-testing:
  stage: deploy
  tags:
    - "shell"
  script:
    - ansible-playbook deploy-for-testing.yml

testing:
  stage: test
  tags:
    - "shell"
  script:
    # 這邊一樣是讓 GitLab Runner 執行 ansible playbook
    - ansible-playbook unit-testing.yml
    - ansible-playbook service-testing.yml
    - ansible-playbook gui-testing.yml

如上面的範例,GitLab Runner 會執行 Ansible Playbook,在 Playbook 中我們就會撰寫目標 Server 需要執行哪些自動化測試的動作,例如 unit-testing.yml 的內容可能會如下 :

- name: unit-testing
  hosts: target_server
  tasks:
    # 這裡以 phpunit 為例
    - name: Run PHP Unit testing
      command: "/usr/bin/phpunit -c phpunit.xml --coverage-text --colors-never"
      args:
        chdir: /code/deploy/path

其他的 playbook 也大同小異,總之會根據不同的自動化測試案例而撰寫不同的內容,到此為止 stage: test 算是處理完畢。

接著既然我們都已經在 CI Pipeline 跑了自動化測試了,那我們該如何查看測試覆蓋率或自動化測試的結果呢?

【新增補充】GitLab 已經變更「測試覆蓋率」的使用方式,因此下面這一段內容已經過期了,如要抓取「測試覆蓋率」請參閱原廠最新文件

這裡也同樣有許多方式,但我們要先理解其實大多數的自動化測試工具都支援將測試結果直接輸出顯示在螢幕上,或者是將測試報告 output 成 text 或 html。因此與之配合多數的 CI Service 也都提供了一些功能來協助判讀測試覆蓋率或將測試報告嵌入 CI Server UI 介面的功能。

GitLab CI 你可以直接進入 test 的 CI Job 查看輸出的測試結果。針對測試覆蓋率 GitLab 則有提供 Test coverage parsing 的功能,只要你有將測試結果 output 記錄於 CI Job 的 Log 中,即可在 Settings > CI/CD > General pipelines 中找到它,然後就根據你要 parsing 的 string 設置。


(GitLab 也貼心的幫你列出常見的幾種測試工具該怎麼爬出測試覆蓋率。)

只要有成功跑完測試,output 出測試覆蓋率且 GitLab CI 有成功 parsing,那麼在你的 CI/CD Pipeline 的介面上,就會出現覆蓋率的百分比數字。


(圖片來自 GitLab 官方文件。)

甚至你還可以將其設定為 Badge,塞進你的 README.md,讓其他人一進入 Project 就能知道這個專案的測試覆蓋率有多高。


(圖片來自 GitLab 官方文件。)

該如何設置 Test coverage parsingBadge 官方都有詳細的文件,這邊就不特別說明了。

小結

今天我們搞定了 stage: test,其實一點都不難,但前提是你不是那個負責撰寫和管理測試案例的那個人(誤)。

總之,今天這個 Stage 有哪些關鍵問題需要處理呢?:

  1. 讓 GitLab Runner 具備與目標 Server 溝通的能力或應該說是操控目標 Server 的能力。
  2. 讓目標 Server 具備執行自動化測試案例的能力。
  3. 如何輸出測試報告給需要的人。
  4. 如何通知測試成功或失敗。

感覺上今天的狀況比較輕鬆一些,因為至少有兩件事是你已經清楚知道,也已經試著處理過的,至於 3、4 則和你使用的自動化測試工具與 CI Service 能否整合有關。如果容易整合也許只要點擊幾下 UI 介面,填幾個參數就能成功設置,如果不好整合,那恐怕你就必須自己在 CI Job 中多做一點功夫,像是自己將測試報告寄出去或傳送至 slack⋯⋯,總之做法也很多種,也受制於你的 CI/CD Pipleine 是怎麼規劃的。
(GitLab CI 的 CI/CD Pipeline 可以與 slack 整合傳遞資訊,這部分我們後續文章會談到。)

今天就到這裡了,我們明天見!

參考資料