在微服務架構中,確保各服務間的協作順暢及整體系統穩定性是至關重要的。本文將探討如何運用 Playwright 撰寫端對端測試,搭配 Docker Compose 建立測試環境,並結合資料函式庫 fixture 確保測試資料一致性,有效驗證微服務應用程式的完整功能。同時,我們也會探討整合測試的策略及工具選擇,並以 FlixTube 應用程式為例,說明如何實踐這些測試方法。最後,我們將會深入探討如何利用 REST API 管理測試資料,以及如何組態 Docker Compose 來模擬真實的執行環境。
資料函式庫連線
資料函式庫連線是微服務與資料函式庫之間的橋樑,負責傳遞查詢和結果。一個良好的資料函式庫連線應該具有高效率、安全性和可擴充套件性。常見的資料函式庫連線技術包括SQL和NoSQL。
測試
測試是確保微服務正確性和可靠性的重要步驟。測試可以分為單元測試、整合測試和系統測試。單元測試負責測試個別元件,整合測試則測試多個元件之間的互動,系統測試則測試整個系統的功能。
測試資料載入
在進行測試之前,需要載入測試資料到資料函式庫中。這個過程稱為資料載入或資料fixture。資料載入可以使用指令碼或程式碼實作,目的是建立一個穩定的測試環境。
測試案例
以下是一個簡單的測試案例:
def test_videos_route():
# 載入測試資料
load_test_data()
# 傳送HTTP請求到/videos路由
response = requests.get('/videos')
# 驗證回應狀態碼和內容
assert response.status_code == 200
assert len(response.json()) > 0
在這個案例中,我們首先載入測試資料,然後傳送HTTP請求到/videos路由,最後驗證回應狀態碼和內容。
圖表翻譯:
這個Mermaid圖表展示了微服務、資料函式庫連線、資料函式庫和測試之間的關係。微服務透過資料函式庫連線存取資料函式庫,同時進行單元測試、整合測試和系統測試,以確保其正確性和可靠性。
9.7 整合測試
整合測試是用於測試多個單元之間的互動,確保它們能夠正確地合作。與單元測試不同,整合測試不會將單元與其依賴項隔離,因此需要考慮到整個系統的行為。
9.7.1 寫整合測試
在 listing 9.9 中,我們可以看到一個簡單的整合測試範例。這個測試使用 Jest 的 beforeAll
函式啟動微服務,並使用 afterAll
函式關閉微服務。這樣可以確保微服務在測試期間保持執行狀態。
beforeAll(async () => {
// 啟動微服務
microservice = await startMicroservice();
});
afterAll(async () => {
// 關閉微服務
await microservice.close();
});
9.7.2 執行整合測試
執行整合測試與執行單元測試類別似,可以使用 npx jest
或 npm test
命令。
9.7.3 整合測試工具
除了 Jest 之外,還有其他整合測試工具可供選擇,例如 Supertest 和 Pact。Supertest 提供了一個簡單的 API,用於向微服務傳送請求和測試回應。Pact 是一個更高階的工具,用於測試微服務之間的通訊。
9.8 端對端測試
端對端測試是測試金字塔的最高層級,旨在測試整個應用程式或其子集。與整合測試類別似,端對端測試不需要模擬依賴項,但需要使用資料固定(database fixtures)來載入真實的測試資料。
端對端測試的挑戰
傳統上,對於分散式應用程式進行端對端測試可能很困難,因為需要組態和啟動所有服務。但是,透過使用 Docker 等工具,可以更容易地實作端對端測試。
端對端測試的優點
端對端測試可以提供對於整個應用程式的全面測試,確保所有元件能夠正確地合作。雖然端對端測試可能比單元測試和整合測試更慢,但它們提供了更高階別的保證,確保應用程式在生產環境中能夠正常執行。
圖表翻譯:
graph LR A[單元測試] --> B[整合測試] B --> C[端對端測試] C --> D[生產環境]
在這個圖表中,我們可以看到從單元測試到整合測試再到端對端測試的流程。每個層級都提供了對於應用程式的不同層次的保證,最終確保應用程式在生產環境中能夠正常執行。
使用Playwright進行端對端測試
Playwright是一種強大的測試工具,能夠載入和測試網頁。它有許多功能,但我們只會學習一些基礎知識,以便開始使用並體驗它的功能。我們將使用Playwright來執行測試,針對FlixTube的前端,該前端由玄貓提供,如圖9.9所示。
執行端對端測試需要啟動整個應用程式(包括資料函式庫),並對前端在網頁瀏覽器中執行的測試。這使得端對端測試成為最慢的測試型別,因此它們位於測試金字塔的頂部。然而,擁有一些端對端測試應該是我們測試策略的一個重要部分。端對端測試涵蓋了很多內容,因此,即使它們需要花費大量時間來執行,但它們也能提供很多價值。此外,這種型別的測試從客戶的角度出發,對我們的應用程式進行測試,這是最重要的觀點,因此我們非常重視端對端測試。
為什麼選擇Playwright?
Playwright是一種非常棒的網頁測試工具。它易於安裝和開始使用,並且具有自動組態生成器,可以在多個瀏覽器上執行測試(甚至可以透明地下載瀏覽器)。玄貓預設情況下,Playwright在無頭(不可見)模式下執行,使得它易於在CI/CD管道中使用。另外,它還具有很好的視覺報表和除錯工具。
安裝Playwright
對於本章和FlixTube,我們將Playwright、端對端測試和一些微服務整合到一個程式碼倉函式庫中。但是,你也可以以其他方式結構化這些內容。你可能希望將Playwright測試放在自己的程式碼倉函式庫中,或將前端和測試放在一起,在一個與其他微服務分開的倉函式庫中。我已經在example-4倉函式庫中包含了你需要的所有內容,以便你可以輕鬆地嘗試。
你可以透過以下命令安裝依賴項:
cd chapter-9/example-4
npm install
我們的應用程式正在使用Docker Compose執行。現在,我們使用了一種叫做Playwright的測試工具來執行端對端測試,針對我們的整個應用程式。
圖表翻譯:
此圖表示了我們如何使用Playwright和Docker Compose進行端對端測試。它展示了我們的應用程式、包含資料函式庫的Docker Compose、Playwright測試工具以及多個JavaScript程式碼檔案,包含我們的測試套件。測試指令碼透過我們的應用程式UI進行互動,應用程式包括一個功能正常的資料函式庫,填充了資料函式庫固定值。
內容解密:
在這個例子中,我們使用Playwright來執行端對端測試,針對FlixTube的前端。這需要啟動整個應用程式,包括資料函式庫,並對前端在網頁瀏覽器中執行的測試。Playwright是一種強大的測試工具,能夠載入和測試網頁,並且具有自動組態生成器,可以在多個瀏覽器上執行測試。透過使用Playwright,我們可以確保我們的應用程式從客戶的角度出發,對我們的應用程式進行測試,這是最重要的觀點,因此我們非常重視端對端測試。
使用 Playwright 進行端對端測試
Playwright 是一個強大的工具,允許我們進行端對端測試。要開始使用 Playwright,我們可以透過以下命令進行初始化:
npm init playwright@latest
這個命令不僅會安裝 Playwright,還會幫助我們設定好組態檔案、範例測試,甚至可以建立一個 GitHub Actions 工作流程檔案,以便於我們的連續整合。
Playwright 安裝與組態
如果我們選擇使用 npm install
安裝 Playwright,則需要手動設定組態檔案。但是,使用 npm init playwright@latest
可以自動完成這些步驟,包括建立組態檔案、範例測試,甚至可以根據我們的選擇生成一個 GitHub Actions 工作流程檔案。
專案結構
安裝 Playwright 後,專案結構會如下所示:
example-4/
docker-compose.yml
package-lock.json
package.json
db-fixture-rest-api/
...
fixtures/
two-videos/
videos.js
gateway/
...
metadata/
...
node_modules/
...
tests/
frontend.test.js
lib/
db-fixture.js
在這個結構中,我們可以看到 Playwright 相關的檔案和目錄,包括測試檔案和組態檔案。
測試範例
以下是一個簡單的測試範例:
// frontend.test.js
const { test, expect } = require('@playwright/test');
test('should load homepage', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toContainText('Welcome to example.com');
});
這個範例展示瞭如何使用 Playwright 進行簡單的網頁測試。
REST API 和資料函式庫固定
除了測試外,Playwright 還可以幫助我們建立 REST API 和資料函式庫固定。以下是一個簡單的範例:
// db-fixture.js
const { RESTAPI } = require('./rest-api');
const fixtures = {
'two-videos': {
videos: [
{ id: 1, title: 'Video 1' },
{ id: 2, title: 'Video 2' },
],
},
};
RESTAPI.loadFixtures(fixtures);
這個範例展示瞭如何使用 Playwright 建立一個 REST API 來載入資料函式庫固定。
Playwright 組態檔案
Playwright 的組態檔案是用於設定 Playwright 的行為和環境的。以下是 Playwright 組態檔案的範例:
const config = {
testDir: './tests',
use: {
//...
},
//...
};
module.exports = config;
在這個範例中,我們設定了 testDir
屬性為 ./tests
,這表示 Playwright 將在 ./tests
目錄下查詢測試檔案。
Docker Compose 檔案
Docker Compose 檔案是用於定義和管理 Docker 容器的。以下是 Docker Compose 檔案的範例:
version: '3'
services:
db-fixtures-rest-api:
build:./db-fixtures-rest-api
ports:
- "8080:8080"
depends_on:
- db
db:
image: postgres
environment:
- POSTGRES_USER=myuser
- POSTGRES_PASSWORD=mypassword
在這個範例中,我們定義了兩個服務:db-fixtures-rest-api
和 db
。db-fixtures-rest-api
服務是用於提供資料函式庫修復的 REST API,而 db
服務是用於提供 PostgreSQL 資料函式庫。
資料函式庫修復
資料函式庫修復是指將資料函式庫還原到一個已知的狀態。以下是資料函式庫修復的範例:
const axios = require('axios');
async function loadFixtures() {
const response = await axios.post('http://localhost:8080/fixtures');
console.log(response.data);
}
async function dropFixtures() {
const response = await axios.delete('http://localhost:8080/fixtures');
console.log(response.data);
}
在這個範例中,我們使用 Axios 函式庫來傳送 HTTP 請求到資料函式庫修復 REST API。loadFixtures
函式用於載入資料函式庫修復,而 dropFixtures
函式用於刪除資料函式庫修復。
Playwright 測試
Playwright 測試是指使用 Playwright 框架來執行測試。以下是 Playwright 測試的範例:
const { test, expect } = require('@playwright/test');
test('example test', async ({ page }) => {
await page.goto('http://localhost:3000');
await expect(page).toContainText('Hello World!');
});
在這個範例中,我們使用 Playwright 的 test
函式來定義一個測試。測試中,我們使用 page
物件來瀏覽網頁,並使用 expect
函式來驗證網頁的內容。
自動化測試的基礎設定
為了確保微服務的正確性和可靠性,自動化測試是一個不可或缺的步驟。在這個章節中,我們將探討如何為一個根據Express的REST API設定自動化測試,特別是當它被佈署在Docker環境中時。
首先,讓我們設定測試專案的基礎設定。這包括定義基礎URL,該URL將是我們執行測試的Web頁面的入口。這對於確保測試的準確性和可靠性至關重要,因為它允許我們在特定的環境中執行測試。
基礎URL的設定
基礎URL是測試過程中的關鍵組成部分,因為它定義了我們將要執行測試的Web頁面的位置。這可以透過設定一個基礎URL變數來實作,這個變數將被用於所有後續的測試請求中。
整合Database Fixtures REST API
在設定自動化測試的過程中,我們需要確保能夠載入和解除安裝資料函式庫中的測試資料。為此,我們可以使用一個REST API來管理資料函式庫中的fixture。這個REST API可以被整合到我們的應用程式中,就像任何其他微服務一樣。
以下是如何使用Docker Compose整合Database Fixtures REST API的示例:
version: '3'
services:
db:
image: mongo:5.0.9
container_name: db
ports:
- "27017:27017"
expose:
- "27017"
restart: always
db-fixture-rest-api:
image: db-fixture-rest-api
build:
context:./db-fixture-rest-api
在這個例子中,我們定義了兩個服務:db
和db-fixture-rest-api
。db
服務使用MongoDB 5.0.9映像,並將連線埠27017暴露給主機。db-fixture-rest-api
服務則使用一個自定義的Docker映像,並從當前目錄下的db-fixture-rest-api
子目錄構建。
Playwright的使用
Playwright是一個強大的瀏覽器自動化工具,允許我們模擬使用者互動並執行端對端的測試。在這個場合,我們可以使用Playwright來載入和解除安裝資料函式庫中的fixture。
以下是使用Playwright載入和解除安裝fixture的示例:
const { test, expect } = require('@playwright/test');
test('load and unload database fixtures', async ({ page }) => {
// 載入fixture
await page.goto('http://localhost:3000/load-fixture');
await expect(page).toContain('Fixture loaded successfully');
// 執行測試
await page.goto('http://localhost:3000/test');
await expect(page).toContain('Test passed successfully');
// 解除安裝fixture
await page.goto('http://localhost:3000/unload-fixture');
await expect(page).toContain('Fixture unloaded successfully');
});
在這個例子中,我們定義了一個測試,用於載入和解除安裝資料函式庫中的fixture。我們使用Playwright的goto
方法導航到負責載入和解除安裝fixture的頁面,並使用expect
方法驗證fixture是否被正確載入和解除安裝。
REST API 測試資料組態
在進行端對端測試時,為了確保測試的可靠性和穩定性,需要準備一套完整的測試資料。這些資料將被用於微服務的測試,尤其是在使用 Playwright 進行網頁測試時。下面將介紹如何使用 REST API 來組態測試資料。
使用 HTTP 進行資料組態
HTTP 是一種廣泛使用的網路協定,透過它可以實作對資料的存取和操作。在測試中,我們可以使用 HTTP 來組態測試資料。例如,透過傳送 HTTP 請求到特定的 API 端點,可以將測試資料寫入到資料函式庫中。
組態 MongoDB 資料函式庫
為了儲存和管理測試資料,需要組態一個 MongoDB 資料函式庫伺服器。這個伺服器將提供一個 REST API,用於存取和操作測試資料。透過這個 API,可以實作對測試資料的建立、讀取、更新和刪除操作。
Docker 化組態
為了方便地組態和管理測試環境,可以使用 Docker 來容器化組態。這樣可以確保測試環境的一致性和可重現性。下面的 Dockerfile 和容器組態示例展示瞭如何組態一個 MongoDB 資料函式庫伺服器和一個 REST API 伺服器,用於提供測試資料。
# 使用官方的 MongoDB 映象
FROM mongo:latest
# 暴露 27017 連線埠給宿主機
EXPOSE 27017
# 設定環境變數
ENV MONGO_INITDB_ROOT_USERNAME=root
ENV MONGO_INITDB_ROOT_PASSWORD=password
version: '3'
services:
db-fixture-rest-api:
build:.
container_name: db-fixture-rest-api
ports:
- "9000:80"
environment:
- MONGO_URI=mongodb://root:password@localhost:27017/
測試資料組態 REST API
組態好 MongoDB 資料函式庫伺服器後,需要實作一個 REST API,用於提供測試資料。這個 API 將提供建立、讀取、更新和刪除測試資料的功能。下面的示例展示瞭如何實作這個 API。
flowchart TD A[傳送 HTTP 請求] --> B[處理請求] B --> C[傳回測試資料] C --> D[更新資料函式庫]
內容解密:
上述流程圖展示瞭如何使用 REST API 來組態測試資料。首先,客戶端傳送一個 HTTP 請求到 API 端點。然後,伺服器處理這個請求,並傳回相應的測試資料。最後,伺服器更新資料函式庫,以確保資料的一致性。
圖表翻譯:
此圖表展示了 REST API 測試資料組態的流程。客戶端傳送 HTTP 請求到 API 端點,伺服器處理請求並傳回測試資料,然後更新資料函式庫以確保資料的一致性。
圖表翻譯:
此圖表使用 Mermaid 語法繪製,展示了 REST API 測試資料組態的流程。客戶端傳送 HTTP 請求到 API 端點,伺服器處理請求並傳回測試資料,然後更新資料函式庫以確保資料的一致性。
flowchart TD A[客戶端傳送 HTTP 請求] --> B[伺服器處理請求] B --> C[傳回測試資料] C --> D[更新資料函式庫]
圖表翻譯:
此圖表展示了 REST API 測試資料組態的流程。客戶端傳送 HTTP 請求到 API 端點,伺服器處理請求並傳回測試資料,然後更新資料函式庫以確保資料的一致性。
使用 Docker Compose 和 Playwright 進行應用程式測試
在進行應用程式測試之前,我們需要確保應用程式已經啟動並執行正常。為了達到這個目的,我們可以使用 Docker Compose 來組態和啟動應用程式的各個元件。
組態 Docker Compose
首先,我們需要組態 Docker Compose 檔案,以便它可以啟動我們的應用程式。以下是 Docker Compose 檔案的一個範例:
version: '3'
services:
app:
build:.
ports:
- "80:80"
depends_on:
- db
restart: always
environment:
- PORT=80
- DBHOST=mongodb://db:27017
- FIXTURES_DIR=fixtures
volumes:
-./fixtures:/usr/src/app/fixtures:z
db:
image: mongo:latest
volumes:
-./data:/data/db
在這個範例中,我們定義了兩個服務:app
和 db
。app
服務是我們的應用程式,db
服務是 MongoDB 資料函式庫。
啟動應用程式
啟動 Docker Compose 之後,我們可以使用以下命令啟動應用程式:
docker-compose up
這個命令會啟動我們的應用程式和 MongoDB 資料函式庫。
載入資料函式庫測試資料
在進行測試之前,我們需要載入資料函式庫測試資料。為了達到這個目的,我們可以使用以下 JavaScript 函式:
const axios = require("axios");
async function loadFixture(databaseName, fixtureName) {
const url = `http://localhost:80/load-fixture?db=${databaseName}&fix=${fixtureName}`;
await axios.get(url);
}
這個函式使用 Axios 來傳送 HTTP GET 請求到資料函式庫測試資料 REST API,從而載入指定的測試資料。
測試應用程式
現在,我們可以使用 Playwright 來測試我們的應用程式。以下是測試程式碼的一個範例:
const { test, expect } = require("@playwright/test");
test("should load fixture", async ({ page }) => {
await loadFixture("mydatabase", "myfixture");
await page.goto("http://localhost:80");
await expect(page).toContainText("我的測試資料");
});
在這個範例中,我們使用 Playwright 來載入測試資料,然後導航到應用程式的首頁,並驗證頁面是否包含指定的文字。
自動化測試的重要性
在微服務架構中,自動化測試對於確保應用程式的正確性和穩定性至關重要。透過撰寫自動化測試,我們可以確保每個微服務都能夠正確地執行其功能,並且能夠與其他微服務進行正確的溝通。
Playwright 測試框架
Playwright 是一個強大的測試框架,允許我們撰寫端對端(end-to-end)的測試。它提供了一個簡單易用的 API,讓我們可以模擬使用者互動,並驗證應用程式的行為。
撰寫 Playwright 測試
在撰寫 Playwright 測試時,我們需要定義一個測試套件(test suite),其中包含多個測試案例(test case)。每個測試案例都會描述一個特定的場景,並驗證應用程式的行為是否符合預期。
以下是一個簡單的 Playwright 測試範例:
const { test, expect } = require('@playwright/test');
const { describe } = test;
const { loadFixture } = require('./lib/db-fixture');
describe('FlixTube 前端', () => {
test('可以列出影片', async ({ page }) => {
await loadFixture('metadata', 'two-videos');
await page.goto('/');
const videos = page.locator('#video-list>div');
await expect(videos).toHaveCount(2);
const firstVideo = videos.nth(0).locator('a');
//...
});
});
在這個範例中,我們定義了一個測試套件 FlixTube 前端
,其中包含一個測試案例 可以列出影片
。在這個測試案例中,我們使用 loadFixture
函式載入一個資料函式庫 fixture,然後使用 page.goto
函式導航到應用程式的首頁。接著,我們使用 page.locator
函式取得影片列表中的元素,並驗證其數量是否正確。
資料函式庫 fixture
在撰寫自動化測試時,資料函式庫 fixture 是一個非常重要的概念。它允許我們建立一個臨時的資料函式庫環境,包含特定的資料,以便我們可以測試應用程式的行為。
以下是一個簡單的資料函式庫 fixture 範例:
const { loadFixture } = require('./lib/db-fixture');
//...
await loadFixture('metadata', 'two-videos');
//...
在這個範例中,我們使用 loadFixture
函式載入一個名為 two-videos
的資料函式庫 fixture,該 fixture 包含兩個影片的資料。
End-to-end 測試實踐
在前端開發中,End-to-end 測試是一種重要的測試方法,旨在驗證整個應用程式的功能性和正確性。以下是使用 Playwright 進行 End-to-end 測試的範例。
從使用者經驗視角出發,本文深入探討了微服務架構中資料函式庫連線、測試流程以及 Playwright 測試框架的應用。透過多維比較分析,我們可以看到單元測試、整合測試和端對端測試在驗證應用程式正確性和可靠性方面扮演的不同角色,也瞭解到測試資料載入的重要性以及如何撰寫有效的測試案例。技術限制深析部分指出端對端測試的挑戰,例如組態和啟動所有服務的複雜性,但同時也提供解決方案,例如使用 Docker 等工具簡化測試流程。文章更進一步分析了 Playwright 的優勢,包括易用性、跨瀏覽器支援以及與 CI/CD 管道的整合。展望未來,隨著微服務架構的普及和測試工具的發展,自動化測試將扮演更重要的角色,而 Playwright 等易用且功能強大的測試框架將成為確保應用程式品質不可或缺的工具。玄貓認為,掌握這些測試方法和工具,對於提升微服務應用程式的穩定性和可靠性至關重要,值得開發團隊投入更多關注和資源。