返回文章列表

Karate Docker CI/CD 管道整合應用

本文探討如何將 Karate API 測試框架整合到 Docker 與 CI/CD 管道中,實作自動化測試流程。文章涵蓋了從 shell 指令碼觸發 Karate 測試、在 Docker 容器中執行測試,以及將測試整合到 GitHub 工作流程等內容,旨在提升 API 測試效率及程式碼品質。

Web 開發 測試

Karate 除了在本地執行 API 測試外,更能整合至 CI/CD 管道,達成自動化測試。本篇文章將逐步說明如何透過 shell 指令碼執行測試,並將測試環境 Docker 化,讓測試流程更彈性且易於管理。如此一來,無論系統是否具備 Java 和 Maven 環境,皆能順利執行測試,同時也能確保測試環境的一致性,降低環境差異造成的測試錯誤。此外,文章也將探討如何客製化測試流程,並整合至 GitHub 工作流程,使開發團隊能更有效率地進行 API 測試,及早發現問題並確保程式碼品質。

Karate 在 Docker 和 CI/CD 管道中的應用

在前面的章節中,我們已經瞭解了 Karate 在 API 測試中的強大功能。然而,到目前為止,我們只在本地系統上執行測試,並且這些測試是由我們臨時執行的。在許多情況下,這是不夠的。相反,這些測試應該在構建管道中自動執行,通常會提取當前的應用程式碼並構建和佈署到測試伺服器,進行測試,並繼續佈署,直到它到達生產環境中的實體伺服器。這個過程稱為持續整合/持續佈署(CI/CD),目標是實作完全自動化的構建和測試流程。

向左移動測試

最近,「向左移動測試」的概念越來越受到關注。這意味著測試應該盡早執行。在 API 測試的情況下,這意味著當 API 的新版本在測試伺服器上可用時,就應該執行測試。這樣,當測試失敗時,更容易跟蹤導致問題的原因。同時,可以自動通知負責 API 開發的正確團隊,而不會有任何延遲。如果所有測試只在系統的所有部分都構建和佈署完成後才執行,那麼要確定哪個團隊負責修復錯誤以及哪個元件導致了錯誤,需要花費更長的時間。

Karate 在 Docker 和 CI/CD 管道中的應用

在本章中,我們將探討不同的方式來執行我們的測試,以適應這些平台並滿足我們的需求。在有限的範圍內,不可能提供一個完整的逐步,介紹如何實作完整的 CI/CD 設定。相反,它旨在提供一些想法和進一步的學習,以幫助實作這一目標。

本章涵蓋的主要主題如下:

  • 從 shell 指令碼觸發 Karate 測試
  • 在 Docker 容器中執行 Karate 測試
  • 自定義我們的測試
  • 將 Karate 測試整合到 GitHub 工作流程中

技術要求

您需要以下內容:

  • 在第 2 章「設定您的 Karate 專案」中完成的系統和整合開發環境(IDE)設定。
  • Git,用於存取 Git 資源並在 Windows 中使用 GitBash shell。它可以從 https://git-scm.com/downloads 下載,適用於所有作業系統。
  • 可選的 GitHub 使用者帳戶,用於使用工作流程。您可以透過 https://github.com/signup 網址註冊。

您可以選擇安裝 Docker Desktop 以在本地系統上執行 Docker。它可以從 https://www.docker.com/get-started 下載和組態。請注意,這不是理解本示例所必需的,並且根據您的作業系統、處理器等可能很複雜。

從 shell 指令碼觸發 Karate 測試

到目前為止,當從命令列執行 Karate 測試時,我們使用了 mvn clean test Maven 命令以及一些引數。這很好用,並且執行良好。但是,必須正確記錄這是如何執行它的,以便其他團隊想要觸發這些測試時知道如何做。此外,它要求測試程式碼在本地系統上可用,並且該系統已安裝 Maven 和 Java。在接下來的章節中,我們將逐步實作一個不需要所有這些東西的解決方案,並且使執行、重用和為第三方設定測試變得更容易。

我們將首先了解如何從 shell 指令碼觸發 Karate 測試 - 成功進行 CI/CD 整合的第一步。

大多數情況下,構建伺服器執行在 Linux 上,因此使用 Bash(大多數 Linux 發行版的預設 shell)是一個好主意。此外,macOS 也內建了這個 shell。對於 Windows,情況則不同。這裡的預設 shell 是命令提示符和 PowerShell。兩者都不相容 Bash。

為 Windows 建立批處理指令碼

如果您想為 Windows 命令提示符(也稱為批處理檔案)建立一個簡單的指令碼來觸發 Karate 測試,可以這樣做。

在 Karate 專案的根目錄中,建立一個以 .bat 結尾的檔案,例如 run-tests.bat。這應該包含用於從命令列執行測試的通常 Maven 命令:

mvn clean test

這是我們執行 Karate 所需的最基本命令。我們現在可以從 Visual Studio(VS)Code 外部的 Windows 命令提示符執行它。為了我們的方便,讓我們使用 VS Code 的終端視窗。在這裡,您需要確保它顯示 cmd 圖示,而不是 powershellbash,以便與命令提示符一起使用。

圖 8.1 – 在 VS Code 的終端中執行批處理檔案

如果它顯示錯誤的圖示,您可以點選旁邊的加號圖示並開啟正確的終端視窗:

圖 8.2 – 選擇命令提示符


#### 內容解密:
1. 使用 `mvn clean test` 命令可以清理並執行 Maven 專案中的測試。
2. 建立 `.bat` 檔案可以簡化 Windows 環境下的測試執行流程。
3. 使用 VS Code 終端執行批處理檔案,需要確認終端型別為命令提示符。
4. 正確設定終端環境後,可以直接執行 `.bat` 檔案來啟動 Karate 測試。

在 Docker 和 CI/CD 管線中執行 Karate

使用批次檔簡化測試執行

若現在執行 run-tests.bat 檔案,應該會看到 VS Code 切換到 Java 視窗並執行 Maven 命令來執行測試。 這看似不是很大的改進,但批次檔中可能包含更多程式碼,例如啟動伺服器、將測試資料新增至資料函式庫等。 想要執行測試的使用者只需執行提供的批次檔,而無需手動記住所有步驟。

在 PowerShell 中執行批次檔

若要在 PowerShell 視窗中執行相同的批次檔,需要輸入 .\run-tests.bat 來呼叫它。 這向 PowerShell 表示該批次指令碼是可信任的。在 Bash 指令碼中也會看到類別似的機制。

建立 Bash 指令碼

Bash 指令碼的副檔名為 .sh,並且應該以標頭行開頭,以指示該指令碼要在哪個殼層上執行。 因此,我們的檔案將被命名為 run-tests.sh,內容如下:

#!/bin/sh
mvn clean test

#! 稱為 shebang,其後的路徑指向要使用的殼層。Bash 的標準路徑是 /bin/sh。目前該命令的其餘部分相同。

在 Linux 或 macOS 上執行 Bash 指令碼

若使用 Linux 或 macOS,可以開啟終端並輸入以下命令來執行該指令碼:

./run-tests.sh

根據所使用的系統和終端,可能會收到錯誤訊息,例如:

permission denied: ./run-tests.sh

這是由於該檔案的許可權問題。若發生這種情況,請確保該檔案具有正確的許可權,以便可以透過輸入以下命令並按下 Enter 鍵來執行:

chmod +x run-tests.sh

chmod 命令(change mode 的縮寫)可用於更改檔案許可權。使用 +x 選項,我們指定該檔案應該是可執行的。之後,執行該檔案應該不會有問題。

在 Docker 容器中執行 Karate 測試

瞭解 Docker

Docker 是一種可以在許多平台上執行的解決方案。它使用一種稱為作業系統層級虛擬化的概念。 這意味著我們可以在作業系統上擁有多個隔離的容器,包括各種自訂工具和設定。 對於在這些容器內執行的程式來說,它們感覺像是一個自成體系的系統。 Docker 的一大優點是,我們可以擁有現成的容器,其中包含執行特定命令所需的所有資源,而無需由使用者個別安裝所有內容。

安裝 Docker

需要在本地系統上安裝 Docker 以嘗試我們的 Docker 化執行。最簡單的方法是透過 Docker Desktop。 這可以在 https://www.docker.com/products/docker-desktop 上找到,支援所有主要作業系統。

啟動和驗證 Docker 安裝

啟動 Docker Desktop 後,需要一段時間才能啟動 Docker Engine。在此過程中,您將看到以下截圖所示的訊息:

此圖示顯示 Docker Desktop 啟動過程。若顯示「Docker Desktop Stopped」或直接關閉,則可能是系統上存在阻止其啟動的更深層問題,例如缺少 WSL 安裝或許可權不足。

最終,它應該如下圖所示: 此圖示顯示 Docker 啟動後的使用者介面。我們也可以透過開啟終端視窗並輸入 docker -v 來驗證它是否正確執行。 這應該會傳回目前的 Docker 版本,如下所示:

Docker version 20.10.22, build 3a2c30b

在 VS Code 的 Git Bash 終端機中執行 Bash 指令碼(Windows)

若您使用的是 Windows,並且已按照本章的技術需求安裝了 Git,則可以將 VS Code 切換到 Git Bash。 這是在 Windows 上對 Bash 的模擬,其行為與真實的 Bash 一樣。

在 Docker 容器中執行 Karate 測試的好處

通常,建置伺服器並不具備執行每種軟體和每個測試框架所需的所有技術。 不幸的是,您並不總是有完整的管理員許可權來簡單地新增缺失的元件或甚至進行完整的設定變更。 我們的 Karate 測試有一些需求,它們需要正確執行:Java 和 Maven。根據您的測試範圍,可能還需要更多的依賴項,這將需要更多的努力來提供。

使用 Docker 的優勢

Docker 可以解決這個問題。它允許我們在容器中執行測試,而無需在本地系統上安裝所有依賴項。

將 Karate 測試 Docker 化

我們將建立一個 Docker 容器,其中包含執行 Karate 測試所需的所有依賴項。這樣,我們就可以在任何具有 Docker 的機器上執行測試。

詳細內容解析:
  1. Bash 指令碼的作用:Bash 指令碼用於簡化測試執行的過程。它包含了執行測試所需的命令,例如 mvn clean test
  2. Docker 的優勢:Docker 提供了一個隔離的環境,用於執行測試。它包含了所有必要的依賴項,使得測試可以在任何具有 Docker 的機器上執行。
  3. 在 VS Code 的 Git Bash 終端機中執行 Bash 指令碼:這使得我們可以在 Windows 上模擬 Linux/macOS 環境,從而能夠執行 Bash 指令碼。

在 Docker 與 CI/CD 管道中執行 Karate

下載 Docker 映像檔

我們的目標是無論系統是否安裝了 Maven 和 Java,都能執行測試。此外,我們希望能夠控制 Maven 的版本,以確保測試按照預期執行。為此,有可以直接下載和使用的 Docker 容器映像檔。在 Maven Docker 映像檔的情況下,這意味著 Docker 可以在任何安裝了 Docker 的系統上使用此映像檔執行容器。這個映像檔提供了 Maven,但前提是容器正在執行。

官方的 Maven 容器映像檔可在 Docker Hub(Docker 的中央容器倉函式庫)上取得。如果檢視 https://hub.docker.com/_/maven,可以看到可用的映像檔。這些映像檔通常由包含軟體名稱和版本的標籤來識別。

圖 8.6 – Docker Hub Maven 概覽

如果我們不關心具體的 Maven 版本,可以直接使用 docker pull maven 命令,下載最新的 Maven 容器。Docker Hub 的右上角也顯示了這一點。

Using default tag: latest
latest: Pulling from library/maven
10ac4908093d: Pull complete
6df15e605e38: Pull complete
...
Digest: sha256:76789e7bf6713b7fe617b0e72ccf1e0cc23425bc41610c878f13a9b2ffd2127d
Status: Downloaded newer image for maven:latest
docker.io/library/maven:latest

這意味著我們現在已經在系統上有了這個容器,但我們還沒有使用它。

在 Docker 容器中執行 Maven 命令

有多種方法可以在 Docker 容器中執行命令。讓我們執行一個命令,然後詳細分析這裡發生了什麼。

在 Windows 上執行 Docker 命令

如果您使用的是 Windows,應該在 Git Bash 中執行以下命令:

docker run --rm --name karate-tests -v "$(pwd)":/usr/src/mymaven -w /usr/src/mymaven maven:3.8.6 mvn -v

在 Windows 上,可能會出現無效路徑的問題。如果出現以下錯誤(xxx 指的是本地系統上的目錄),應該新增 MSYS_NO_PATHCONV=1 環境變數:

MSYS_NO_PATHCONV=1 docker run --rm --name karate-tests -v "$(pwd)":/usr/src/mymaven -w /usr/src/mymaven maven:3.8.6 mvn -v

這使得在 Windows 上可以使用相對路徑。

解析 Docker 命令

讓我們逐行分析這個命令:

  1. docker run 可以執行一個與主機系統隔離的容器。預設情況下,除非特別指定,否則在容器內執行的程式無法存取主機系統。
  2. --rm 選項會在容器內執行的命令停止後刪除容器。這意味著只有在需要時才會執行容器。
  3. --name 可以為容器命名,以便在執行時識別它,例如在 Docker Desktop 容器的標籤中。
  4. -v 可以指定主機系統上的目錄或檔案,並使其在容器內可存取。這裡,我們使用 $(pwd) 命令取得目前 Docker 命令執行的目錄。冒號後面可以指定這個目錄在容器內的名稱。在這種情況下,它是 /usr/src/mymaven。本質上,我們正在建立一個到主機系統上目錄的橋樑。這被稱為掛載。
  5. -w 將之前掛載的目錄設為 Docker 容器的工作目錄。這意味著容器現在會進入與主機系統相同的目錄,並在這個目錄中執行後續命令。
  6. 後面跟著的是我們要使用的容器映像檔名稱,也就是我們的 Maven 映像檔,標籤為 maven:3.8.6
  7. 最後,Maven 容器接受一個 Maven 命令作為引數。這裡,我們使用 mvn -v,它會顯示目前的 Maven 版本。注意,無論主機系統上安裝的 Maven 版本是什麼,這裡都應該顯示 3.8.6,因為它是執行容器內的 Maven 版本。

程式碼範例

docker run \
--rm \
--name karate-tests \
-v "$(pwd)":/usr/src/mymaven \
-w /usr/src/mymaven \
maven:3.8.6 \
mvn -v

內容解密:

  1. 使用 docker run 命令來啟動一個新的容器。
  2. --rm 確保命令執行完畢後自動刪除容器。
  3. --name karate-tests 為容器命名,方便識別和管理。
  4. -v "$(pwd)":/usr/src/mymaven 將目前主機目錄掛載到容器的 /usr/src/mymaven 目錄下,實作資料分享。
  5. -w /usr/src/mymaven 設定容器的工作目錄為掛載的目錄。
  6. maven:3.8.6 指定使用的 Docker 映像檔及其版本。
  7. mvn -v 是傳遞給容器的命令,用於顯示 Maven 的版本資訊。

在 Maven Docker 容器中執行 Karate 測試

在上一節中,我們使用 mvn -v 作為範例命令來測試我們的 Maven 容器。也許您已經看出這與透過 Maven 觸發 Karate 有關;我們可以直接給容器下達 Karate 的命令。然而,這只有在從 Karate 測試 pom.xml 檔案所在的目錄下執行 docker run 命令時才有效:

docker run \
--rm --name karate-tests \
-v"$(pwd)":/usr/src/mymaven \
-w /usr/src/mymaven \
maven:3.8.6 \
mvn clean test

這將使用 mvn clean test 命令執行 Maven 容器,從而觸發我們的 Karate 測試。由於這與主機系統相連,我們甚至可以在目標目錄下找到我們的測試報告,就像沒有使用 Docker 一樣!

在 Docker 中執行我們的 Shell 指令碼

讓我們回到之前的小型 Shell 指令碼。記住這最終是我們想要使用的,因為我們可以在未來為它新增更多的功能。我們已經將啟動 Docker 命令的目前目錄掛載起來。這個目錄也託管了我們的 Shell 指令碼。因此,我們現在可以執行 Shell 指令碼,而不是之前的 mvn clean test 命令:

docker run \
--rm --name karate-tests \
-v"$(pwd)":/usr/src/mymaven \
-w /usr/src/mymaven \
maven:3.8.6 \
./run-tests.sh

內容解密:

  1. ./run-tests.sh 是要執行的指令碼檔案,需確保該檔案具有執行許可權。
  2. 指令碼執行依賴於掛載的主機目錄下的檔案結構和內容。
  3. 這種方式使得測試執行更加靈活和可控,可以根據需要修改指令碼內容。