원클릭으로
webapi-real-testing
Web API 測試實作技能,協助開發者使用 Testcontainers + Reqnroll 撰寫完整的 API 整合測試,包含 Docker 測試環境、BDD 情境定義與測試步驟實作。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Web API 測試實作技能,協助開發者使用 Testcontainers + Reqnroll 撰寫完整的 API 整合測試,包含 Docker 測試環境、BDD 情境定義與測試步驟實作。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
API 開發流程引導技能,協助開發者選擇合適的開發流程(API First 或 Code First),並提供 OpenAPI 規格管理、程式碼產生等自動化支援。
BDD 測試實作技能,協助開發者使用 Reqnroll 撰寫行為驅動開發測試,包含 Gherkin 語法、測試步驟實作與 Docker 測試環境設定。
快取策略與多層快取設計技能,協助開發者實作 L1 Memory + L2 Redis 分層快取,包含 TTL 管理、版本控制與失效策略。
EF Core 操作與最佳化技能,協助開發者正確使用 Entity Framework Core,包含 DbContextFactory 模式、查詢最佳化、Migration 管理與反向工程。
專案初始化與配置技能,負責引導使用者完成新專案的初始化、配置設定、GitHub 範本套用與專案狀態檢測。
Repository 設計指導技能,協助開發者根據業務需求選擇最合適的 Repository 設計策略(資料表導向 vs 需求導向 vs 混合模式)。
| name | webapi-real-testing |
| description | Web API 測試實作技能,協助開發者使用 Testcontainers + Reqnroll 撰寫完整的 API 整合測試,包含 Docker 測試環境、BDD 情境定義與測試步驟實作。 |
Web API 測試實作技能,協助開發者使用 Testcontainers + Reqnroll 撰寫完整的 API 整合測試,包含 Docker 測試環境、BDD 情境定義與測試步驟實作。
💡 獨立用戶提示:所有參考檔案與範本自動使用 FileResolver 工具。 即使您沒有下載完整專案,SKILL 也會自動從 GitHub 取得所需的測試範本與範例。 無需手動複製
dotnet-project-template的測試專案。
@workspace 我想要實作 Web API 測試
使用 webapi-testing 撰寫 API 測試
當使用者要求實作 Web API 測試時,必須優先檢測測試專案狀態:
.csproj 專案檔案
**/*[Tt]est*.csproj*.Test.csproj, *.Tests.csproj, *.IntegrationTest.csproj, *.UnitTest.csproj**/Test/ 或 **/Tests/ 目錄BaseStep.cs 或 TestServer.cs 等核心測試檔案AI 助理應使用適合當前環境的工具搜尋測試專案:
搜尋模式:**/*[Tt]est*.csproj(不分大小寫)
工具選擇:
Glob 工具(pattern: **/*[Tt]est*.csproj)或 Grep 工具輸出要求:
graph TD
A[AI 助理啟動] --> B{檢查包含 test 的 .csproj<br/>**/*test*.csproj}
B -->|存在| C{驗證測試專案結構完整性}
B -->|不存在| D[觸發測試專案建立對話]
C -->|完整| E[正常測試開發模式]
C -->|不完整| D
D --> F[詢問是否建立測試專案]
F -->|是| G[詢問建立方式]
F -->|否| H[結束流程]
G -->|空白專案| I[詢問測試框架]
G -->|複製範本| J[詢問測試專案名稱與位置]
I -->|xUnit| K1[詢問測試專案名稱與位置]
I -->|NUnit| K2[詢問測試專案名稱與位置]
I -->|MSTest| K3[詢問測試專案名稱與位置]
K1 --> L1[使用 dotnet new xunit 建立]
K2 --> L2[使用 dotnet new nunit 建立]
K3 --> L3[使用 dotnet new mstest 建立]
J --> M1[透過 FileResolver 自動取得測試專案範本]
L1 --> M2[安裝必要套件]
L2 --> M2
L3 --> M2
M1 --> M3[重新命名與更新命名空間]
M2 --> N[建立測試專案核心架構]
M3 --> O[驗證複製是否成功]
N --> P{偵測方案檔案數量}
O --> P
P -->|1個| Q[自動加入該方案]
P -->|多個| R[詢問要加入到哪個方案]
P -->|0個| S[警告:無方案檔案,跳過加入]
Q --> E
R --> E
S --> E
問題:
⚠️ 偵測到專案尚未建立整合測試專案
請選擇:
1️⃣ 是,我要建立測試專案
- 建立完整的整合測試專案
- 包含 BDD 測試架構與 Docker 測試環境
2️⃣ 否,暫時不需要
- 稍後再建立測試專案
- 可隨時回來建立
請選擇:
不得假設:不可擅自假設使用者一定要建立測試專案,必須明確詢問。
問題:
請選擇測試專案建立方式:
1️⃣ 建立空白測試專案
✅ 使用 dotnet new 建立基礎專案
✅ 需要手動配置測試架構
✅ 適合:自訂測試結構、最小化依賴
⚠️ 需要較多設定工作
2️⃣ 複製完整測試專案範本(推薦)
✅ 透過 FileResolver 自動取得完整測試專案範本(無需手動下載專案)
✅ 包含完整的測試架構(BaseStep、TestServer、範例測試)
✅ 適合:快速啟動、遵循專案規範
⚠️ 需要調整命名空間
請選擇:
不得假設:不可擅自選擇建立方式,必須明確詢問使用者。
問題:
請選擇測試框架:
1️⃣ xUnit(推薦)
✅ 現代化的測試框架
✅ 專案預設使用的框架
✅ 支援平行測試執行
✅ 良好的社群支援
2️⃣ NUnit
✅ 傳統且成熟的測試框架
✅ 豐富的斷言 API
✅ 適合從 Java JUnit 遷移的團隊
⚠️ 需要手動整合 Reqnroll
3️⃣ MSTest
✅ Microsoft 官方測試框架
✅ 與 Visual Studio 深度整合
✅ 適合企業環境
⚠️ 社群支援較少
請選擇:
不得假設:不可擅自使用 xUnit,必須明確詢問使用者選擇。
問題:
請提供測試專案名稱:
範例:
- {ProjectName}.IntegrationTest
- {ProjectName}.Job.IntegrationTest
- {SolutionName}.IntegrationTest
請輸入測試專案名稱:
不得假設:不可擅自使用預設名稱,必須明確詢問使用者。
問題:
請選擇測試專案建立位置:
1️⃣ src/be/{ProjectName}.IntegrationTest/(推薦)
- 與主專案同層,結構清晰
- 符合 .NET 專案慣例
2️⃣ tests/{ProjectName}.IntegrationTest/
- 所有測試集中管理
- 適合多個測試專案
3️⃣ 自訂路徑
- 自行指定測試專案位置
請選擇:
不得假設:不可擅自使用預設位置,必須明確詢問使用者。
當偵測到恰好 1 個解決方案檔案時,為了簡化流程,會自動加入該方案,無需詢問使用者。這是唯一不需要詢問的情境。
理由:
其他情況(0個或多個方案)仍須遵循強制詢問原則。
偵測邏輯:
問題(僅當偵測到多個 .sln 時詢問):
偵測到多個解決方案檔案,請選擇要加入測試專案的方案:
1️⃣ JobBank1111.sln
- 主要解決方案
- 包含所有專案
2️⃣ JobBank1111.Backend.sln
- 後端專案解決方案
- 僅包含後端相關專案
3️⃣ 不加入任何方案
- 手動管理專案參考
請選擇:
不得假設:偵測到多個方案時,不可擅自選擇,必須明確詢問使用者。
根據使用者選擇的測試框架(xUnit/NUnit/MSTest),執行對應的建立流程。
xUnit 範例:
# 建立測試專案
dotnet new xunit -n {ProjectName}.IntegrationTest -o src/be/{ProjectName}.IntegrationTest
# 加入到解決方案
dotnet sln add src/be/{ProjectName}.IntegrationTest/{ProjectName}.IntegrationTest.csproj
# 加入專案參考
dotnet add src/be/{ProjectName}.IntegrationTest/{ProjectName}.IntegrationTest.csproj reference src/be/{ProjectName}.WebAPI/{ProjectName}.WebAPI.csproj
NUnit 範例:
# 建立測試專案
dotnet new nunit -n {ProjectName}.IntegrationTest -o src/be/{ProjectName}.IntegrationTest
# 加入到解決方案
dotnet sln add src/be/{ProjectName}.IntegrationTest/{ProjectName}.IntegrationTest.csproj
# 加入專案參考
dotnet add src/be/{ProjectName}.IntegrationTest/{ProjectName}.IntegrationTest.csproj reference src/be/{ProjectName}.WebAPI/{ProjectName}.WebAPI.csproj
MSTest 範例:
# 建立測試專案
dotnet new mstest -n {ProjectName}.IntegrationTest -o src/be/{ProjectName}.IntegrationTest
# 加入到解決方案
dotnet sln add src/be/{ProjectName}.IntegrationTest/{ProjectName}.IntegrationTest.csproj
# 加入專案參考
dotnet add src/be/{ProjectName}.IntegrationTest/{ProjectName}.IntegrationTest.csproj reference src/be/{ProjectName}.WebAPI/{ProjectName}.WebAPI.csproj
根據測試框架安裝對應的 Reqnroll 套件與其他必要套件。
xUnit 範例:
# 進入測試專案目錄
cd src/be/{ProjectName}.IntegrationTest
# 核心測試框架
dotnet add package xUnit --version 2.9.2
dotnet add package Microsoft.AspNetCore.Mvc.Testing --version 8.0.0
# BDD 測試框架
dotnet add package Reqnroll --version 2.1.1
dotnet add package Reqnroll.xUnit --version 2.1.1
# Docker 測試容器
dotnet add package Testcontainers --version 3.10.0
dotnet add package Testcontainers.MsSql --version 3.10.0
dotnet add package Testcontainers.Redis --version 3.10.0
# HTTP 客戶端與序列化
dotnet add package Refit --version 8.0.0
dotnet add package System.Text.Json --version 8.0.0
# JSON 驗證
dotnet add package JsonDiffPatch.Net --version 2.3.0
dotnet add package Newtonsoft.Json --version 13.0.3
# 假資料產生
dotnet add package Bogus --version 35.6.1
# 時間模擬
dotnet add package Microsoft.Extensions.TimeProvider.Testing --version 8.10.0
# 回到根目錄
cd ../../..
NUnit 範例:
# 進入測試專案目錄
cd src/be/{ProjectName}.IntegrationTest
# 核心測試框架
dotnet add package NUnit --version 4.0.1
dotnet add package NUnit3TestAdapter --version 4.5.0
dotnet add package Microsoft.AspNetCore.Mvc.Testing --version 8.0.0
# BDD 測試框架
dotnet add package Reqnroll --version 2.1.1
dotnet add package Reqnroll.NUnit --version 2.1.1
# Docker 測試容器與其他套件(同 xUnit)
dotnet add package Testcontainers --version 3.10.0
dotnet add package Testcontainers.MsSql --version 3.10.0
dotnet add package Testcontainers.Redis --version 3.10.0
dotnet add package Refit --version 8.0.0
dotnet add package System.Text.Json --version 8.0.0
dotnet add package JsonDiffPatch.Net --version 2.3.0
dotnet add package Newtonsoft.Json --version 13.0.3
dotnet add package Bogus --version 35.6.1
dotnet add package Microsoft.Extensions.TimeProvider.Testing --version 8.10.0
# 回到根目錄
cd ../../..
MSTest 範例:
# 進入測試專案目錄
cd src/be/{ProjectName}.IntegrationTest
# 核心測試框架
dotnet add package MSTest.TestFramework --version 3.2.0
dotnet add package MSTest.TestAdapter --version 3.2.0
dotnet add package Microsoft.AspNetCore.Mvc.Testing --version 8.0.0
# BDD 測試框架
dotnet add package Reqnroll --version 2.1.1
dotnet add package Reqnroll.MSTest --version 2.1.1
# Docker 測試容器與其他套件(同 xUnit)
dotnet add package Testcontainers --version 3.10.0
dotnet add package Testcontainers.MsSql --version 3.10.0
dotnet add package Testcontainers.Redis --version 3.10.0
dotnet add package Refit --version 8.0.0
dotnet add package System.Text.Json --version 8.0.0
dotnet add package JsonDiffPatch.Net --version 2.3.0
dotnet add package Newtonsoft.Json --version 13.0.3
dotnet add package Bogus --version 35.6.1
dotnet add package Microsoft.Extensions.TimeProvider.Testing --version 8.10.0
# 回到根目錄
cd ../../..
建立以下核心檔案(根據測試框架調整屬性):
參考檔案(透過 FileResolver 自動取得):JobBank1111.Job.IntegrationTest/ 目錄下的對應檔案
注意:不同測試框架的屬性差異:
[BeforeTestRun], [BeforeScenario][BeforeTestRun], [Before][AssemblyInitialize], [TestInitialize]建立 appsettings.Test.json(若需要):
{
"Logging": {
"LogLevel": {
"Default": "Information"
}
},
"TestContainers": {
"SqlServer": {
"Image": "mcr.microsoft.com/mssql/server:2022-latest",
"Port": 1433
},
"Redis": {
"Image": "redis:7-alpine",
"Port": 6379
}
}
}
SKILL 自動提供範本檔案,開發者可參考這些範本建立測試專案(透過 FileResolver 自動取得,無需手動複製 dotnet-project-template)。
AI 助理應執行以下操作:
取得測試專案範本(透過 FileResolver 自動取得)
JobBank1111.Job.IntegrationTest(完整測試專案架構)src/be/{ProjectName}.IntegrationTest取得測試共用範本(若存在,透過 FileResolver 自動取得)
JobBank1111.Testing.Commonsrc/be/{ProjectName}.Testing.CommonAI 助理應重新命名以下檔案:
測試專案檔案
JobBank1111.Job.IntegrationTest.csproj{ProjectName}.IntegrationTest.csproj測試共用專案檔案(若存在)
JobBank1111.Testing.Common.csproj{ProjectName}.Testing.Common.csprojAI 助理應批次替換所有 .cs 檔案中的命名空間:
替換規則:
JobBank1111.Job.IntegrationTest → {ProjectName}.IntegrationTestJobBank1111.Testing.Common → {ProjectName}.Testing.Common處理範圍:
src/be/{ProjectName}.IntegrationTestsrc/be/{ProjectName}.Testing.Common(若存在).cs 檔案注意事項:
更新 .csproj 檔案中的專案參考路徑:
# 更新測試專案的專案參考
dotnet add src/be/{ProjectName}.IntegrationTest/{ProjectName}.IntegrationTest.csproj `
reference src/be/{ProjectName}.WebAPI/{ProjectName}.WebAPI.csproj
dotnet add src/be/{ProjectName}.IntegrationTest/{ProjectName}.IntegrationTest.csproj `
reference src/be/{ProjectName}.Testing.Common/{ProjectName}.Testing.Common.csproj
# 加入到解決方案
dotnet sln add src/be/{ProjectName}.IntegrationTest/{ProjectName}.IntegrationTest.csproj
dotnet sln add src/be/{ProjectName}.Testing.Common/{ProjectName}.Testing.Common.csproj
檢查以下項目:
# 建置測試專案驗證
dotnet build src/be/{ProjectName}.IntegrationTest/{ProjectName}.IntegrationTest.csproj
建立完成後,驗證以下結構是否正確:
src/be/{ProjectName}.IntegrationTest/
├── BaseStep.cs
├── TestServer.cs
├── ScenarioContextExtension.cs
├── DbContextExtensions.cs
├── _01_Demo/
│ ├── Demo.feature
│ └── DemoStep.cs
└── {ProjectName}.IntegrationTest.csproj
AI: 正在檢測測試專案狀態...
AI: ⚠️ 偵測到專案尚未建立整合測試專案
AI: 【問題 1/5】請選擇:
1️⃣ 是,我要建立測試專案
2️⃣ 否,暫時不需要
使用者: 1
AI: ✅ 確認建立測試專案
AI: 【問題 2/5】請選擇測試專案建立方式:
1️⃣ 建立空白測試專案
2️⃣ 複製完整測試專案範本(推薦)
使用者: 1
AI: ✅ 建立空白測試專案
AI: 【問題 3/5】請選擇測試框架:
1️⃣ xUnit(推薦)
2️⃣ NUnit
3️⃣ MSTest
使用者: 1
AI: ✅ 測試框架:xUnit
AI: 【問題 4/5】請提供測試專案名稱:
範例:
- JobBank1111.Job.IntegrationTest(推薦)
- {ProjectName}.IntegrationTest
使用者: JobBank1111.Job.IntegrationTest
AI: ✅ 測試專案名稱:JobBank1111.Job.IntegrationTest
AI: 【問題 5/5】請選擇測試專案建立位置:
1️⃣ src/be/JobBank1111.Job.IntegrationTest/(推薦)
2️⃣ tests/JobBank1111.Job.IntegrationTest/
3️⃣ 自訂路徑
使用者: 1
AI: ✅ 測試專案位置:src/be/JobBank1111.Job.IntegrationTest/
AI: 🔍 正在偵測解決方案檔案...
✅ 偵測到 1 個解決方案檔案:JobBank1111.sln
ℹ️ 將自動加入到該解決方案
AI: 📋 配置摘要:
- 建立方式:空白測試專案
- 測試框架:xUnit 2.9.2
- 測試專案名稱:JobBank1111.Job.IntegrationTest
- 建立位置:src/be/JobBank1111.Job.IntegrationTest/
- 加入方案:JobBank1111.sln(自動偵測)
- BDD 框架:Reqnroll.xUnit 2.1.1
- Docker 容器:Testcontainers 3.10.0
AI: 開始建立測試專案...
AI: 📦 正在建立 xUnit 測試專案...
✅ dotnet new xunit 完成
AI: 🔗 正在加入專案參考...
✅ 已加入到解決方案 JobBank1111.sln
✅ 已參考主專案
AI: 📥 正在安裝 NuGet 套件...
✅ xUnit 2.9.2
✅ Microsoft.AspNetCore.Mvc.Testing 8.0.0
✅ Reqnroll.xUnit 2.1.1
✅ Testcontainers 3.10.0
✅ Testcontainers.MsSql 3.10.0
✅ Testcontainers.Redis 3.10.0
(共 11 個套件)
AI: 📝 正在建立測試核心架構...
✅ BaseStep.cs
✅ TestServer.cs
✅ ScenarioContextExtension.cs
✅ DbContextExtensions.cs
✅ _01_Demo/Demo.feature
✅ _01_Demo/DemoStep.cs
AI: 🎉 測試專案建立完成!
AI: 📖 下一步建議:
1. 執行 `task test-integration` 驗證測試環境
2. 參考 `_01_Demo/Demo.feature` 撰寫測試情境
3. 使用 `task api-dev` 啟動 API 以便測試
AI: 正在檢測測試專案狀態...
AI: ⚠️ 偵測到專案尚未建立整合測試專案
AI: 【問題 1/4】請選擇:
1️⃣ 是,我要建立測試專案
2️⃣ 否,暫時不需要
使用者: 1
AI: ✅ 確認建立測試專案
AI: 【問題 2/4】請選擇測試專案建立方式:
1️⃣ 建立空白測試專案
2️⃣ 複製完整測試專案範本(推薦)
使用者: 2
AI: ✅ 複製完整測試專案範本
AI: 【問題 3/4】請提供測試專案名稱:
範例:
- JobBank1111.Job.IntegrationTest(推薦)
- {ProjectName}.IntegrationTest
使用者: JobBank1111.Job.IntegrationTest
AI: ✅ 測試專案名稱:JobBank1111.Job.IntegrationTest
AI: 【問題 4/4】請選擇測試專案建立位置:
1️⃣ src/be/JobBank1111.Job.IntegrationTest/(推薦)
2️⃣ tests/JobBank1111.Job.IntegrationTest/
3️⃣ 自訂路徑
使用者: 1
AI: ✅ 測試專案位置:src/be/JobBank1111.Job.IntegrationTest/
AI: 📋 配置摘要:
- 建立方式:複製完整測試專案範本
- 測試框架:xUnit 2.9.2(從範本)
- 測試專案名稱:JobBank1111.Job.IntegrationTest
- 建立位置:src/be/JobBank1111.Job.IntegrationTest/
- 包含:完整測試架構、範例測試、測試輔助工具
AI: 開始複製測試專案範本...
AI: 📦 正在複製測試專案檔案...
✅ 已複製 JobBank1111.Job.IntegrationTest
✅ 已複製 JobBank1111.Testing.Common
AI: 🔄 正在重新命名專案檔案...
✅ 已重新命名 .csproj 檔案
AI: 🔧 正在更新命名空間...
✅ 已更新 39 個檔案的命名空間
AI: 🔗 正在更新專案參考...
✅ 已加入到解決方案
✅ 已更新專案參考
AI: ✅ 正在驗證專案...
✅ 專案建置成功
AI: 🎉 測試專案建立完成!
AI: 📖 下一步建議:
1. 執行 `task test-integration` 驗證測試環境
2. 參考 `_01_Demo/飯粒.feature` 了解測試範例
3. 根據需求調整測試架構與設定
AI: 正在檢測測試專案狀態...
AI: ⚠️ 偵測到專案尚未建立整合測試專案
AI: 【問題 1/6】請選擇:
1️⃣ 是,我要建立測試專案
2️⃣ 否,暫時不需要
使用者: 1
AI: ✅ 確認建立測試專案
AI: 【問題 2/6】請選擇測試專案建立方式:
1️⃣ 建立空白測試專案
2️⃣ 複製完整測試專案範本(推薦)
使用者: 1
AI: ✅ 建立空白測試專案
AI: 【問題 3/6】請選擇測試框架:
1️⃣ xUnit(推薦)
2️⃣ NUnit
3️⃣ MSTest
使用者: 1
AI: ✅ 測試框架:xUnit
AI: 【問題 4/6】請提供測試專案名稱:
範例:
- JobBank1111.Job.IntegrationTest(推薦)
- {ProjectName}.IntegrationTest
使用者: JobBank1111.Job.IntegrationTest
AI: ✅ 測試專案名稱:JobBank1111.Job.IntegrationTest
AI: 【問題 5/6】請選擇測試專案建立位置:
1️⃣ src/be/JobBank1111.Job.IntegrationTest/(推薦)
2️⃣ tests/JobBank1111.Job.IntegrationTest/
3️⃣ 自訂路徑
使用者: 1
AI: ✅ 測試專案位置:src/be/JobBank1111.Job.IntegrationTest/
AI: 🔍 正在偵測解決方案檔案...
⚠️ 偵測到 2 個解決方案檔案
AI: 【問題 6/6】請選擇要加入測試專案的方案:
1️⃣ JobBank1111.sln
- 主要解決方案
- 包含所有專案
2️⃣ JobBank1111.Backend.sln
- 後端專案解決方案
- 僅包含後端相關專案
3️⃣ 不加入任何方案
- 手動管理專案參考
使用者: 1
AI: ✅ 選擇方案:JobBank1111.sln
AI: 📋 配置摘要:
- 建立方式:空白測試專案
- 測試框架:xUnit 2.9.2
- 測試專案名稱:JobBank1111.Job.IntegrationTest
- 建立位置:src/be/JobBank1111.Job.IntegrationTest/
- 加入方案:JobBank1111.sln
- BDD 框架:Reqnroll.xUnit 2.1.1
- Docker 容器:Testcontainers 3.10.0
AI: 開始建立測試專案...
AI: 📦 正在建立 xUnit 測試專案...
✅ dotnet new xunit 完成
AI: 🔗 正在加入專案參考...
✅ 已加入到解決方案 JobBank1111.sln
✅ 已參考主專案
AI: 📥 正在安裝 NuGet 套件...
✅ xUnit 2.9.2
✅ Microsoft.AspNetCore.Mvc.Testing 8.0.0
✅ Reqnroll.xUnit 2.1.1
✅ Testcontainers 3.10.0
✅ Testcontainers.MsSql 3.10.0
✅ Testcontainers.Redis 3.10.0
(共 11 個套件)
AI: 📝 正在建立測試核心架構...
✅ BaseStep.cs
✅ TestServer.cs
✅ ScenarioContextExtension.cs
✅ DbContextExtensions.cs
✅ _01_Demo/Demo.feature
✅ _01_Demo/DemoStep.cs
AI: 🎉 測試專案建立完成!
AI: 📖 下一步建議:
1. 執行 `task test-integration` 驗證測試環境
2. 參考 `_01_Demo/Demo.feature` 撰寫測試情境
3. 使用 `task api-dev` 啟動 API 以便測試
dotnet new 或複製範本dotnet add package管理測試生命週期與提供可重用的 Gherkin 步驟定義。
核心職責:
關鍵方法:
[BeforeTestRun]
public static async Task BeforeTestRun()
{
// 建立 Docker 容器(SQL Server、Redis、MockServer)
// 設定環境變數
// 初始化資料庫
}
[BeforeScenario]
public async Task BeforeScenario()
{
// 清空資料庫資料
}
參考檔案(透過 FileResolver 取得):JobBank1111.Job.IntegrationTest/BaseStep.cs
建立與管理測試所需的 Docker 容器。
支援的容器:
CreateMsSqlContainerAsync()CreateRedisContainerAsync()CreatePostgreSqlContainerAsync()CreateMockServerContainerAsync()使用範例:
var msSqlContainer = await TestContainerFactory.CreateMsSqlContainerAsync();
var dbConnectionString = msSqlContainer.GetConnectionString();
var redisContainer = await TestContainerFactory.CreateRedisContainerAsync();
var redisUrl = redisContainer.GetConnectionString();
var mockServerContainer = await TestContainerFactory.CreateMockServerContainerAsync();
var externalUrl = TestContainerFactory.GetMockServerConnection(mockServerContainer);
參考檔案(透過 FileResolver 取得):JobBank1111.Testing.Common/TestContainerFactory.cs
模擬 Web API 執行環境。
核心功能:
實作範例:
public class TestServer(DateTimeOffset now, string userId)
: WebApplicationFactory<Program>
{
private void ConfigureServices(IServiceCollection services)
{
// 註冊測試用 Controller
services.AddControllers()
.AddApplicationPart(typeof(TestController).Assembly);
// 模擬身分
services.AddFakeContextAccessor(userId);
// 模擬現在時間
var fakeTimeProvider = new FakeTimeProvider(now);
services.AddSingleton<TimeProvider>(fakeTimeProvider);
}
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(this.ConfigureServices);
}
}
參考檔案(透過 FileResolver 取得):JobBank1111.Job.IntegrationTest/TestServer.cs
管理測試情境中的狀態與資料。
管理項目:
常用方法:
// 設定測試伺服器
context.SetHttpClient(httpClient);
context.SetServiceProvider(server.Services);
// 設定測試資料
context.SetUserId("admin");
context.SetUtcNow(DateTimeOffset.Parse("2000-01-01T00:00:00+00:00"));
// 準備 HTTP 請求
context.AddHttpHeader("x-trace-id", "TEST-001");
context.AddQueryString("pageSize", "10");
context.SetHttpRequestBody(jsonBody);
// 取得回應
var statusCode = context.GetHttpStatusCode();
var responseBody = context.GetHttpResponseBody();
var jsonNode = context.GetJsonNode();
// 取得資料庫
var dbFactory = context.GetMemberDbContextFactory();
參考檔案(透過 FileResolver 取得):JobBank1111.Job.IntegrationTest/ScenarioContextExtension.cs
資料庫測試相關的擴充方法。
核心功能:
// 初始化測試資料庫(執行 Migration 或 EnsureCreated)
await dbContext.Initial();
// 清空所有資料表
dbContext.ClearAllData();
// 執行種子資料(執行 DB/Scripts/*.sql)
await dbContext.Seed();
安全機制:
// 只允許 localhost 執行清空資料操作
SqlServerGenerateScript.OnlySupportLocal(connectionString);
參考檔案(透過 FileResolver 取得):JobBank1111.Job.IntegrationTest/DbContextExtensions.cs
使用 MockServer 容器模擬外部 API。
核心功能:
// 建立假端點
await MockedServerAssistant.PutNewEndPointAsync(
client,
httpMethod: "POST",
relativePath: "/external/api/notify",
statusCode: 200,
body: "{\"success\": true}"
);
// 重置 MockServer
await MockedServerAssistant.ResetAsync(client);
參考檔案(透過 FileResolver 取得):JobBank1111.Testing.Common/MockServer/MockedServerAssistant.cs
graph TD
A[BeforeTestRun] --> B[建立 Docker 容器]
B --> C[SQL Server 容器]
B --> D[Redis 容器]
B --> E[MockServer 容器]
C --> F[設定環境變數]
D --> F
E --> F
F --> G[初始化資料庫 Migration/Seed]
G --> H[建立 ServiceProvider]
H --> I[BeforeScenario 清空資料]
I --> J[執行測試情境]
J --> I
graph LR
A[Given: 初始化測試伺服器] --> B[Given: 準備測試資料]
B --> C[Given: 準備 HTTP 請求參數]
C --> D[When: 執行 API 請求]
D --> E[Then: 驗證 HTTP 狀態碼]
E --> F[Then: 驗證回應內容]
F --> G[Then: 驗證資料庫狀態]
請選擇需要實作的測試範圍:
1️⃣ 完整測試(BDD 整合測試 + 單元測試)
✅ API 端點測試(透過 WebApplicationFactory)
✅ Handler 業務邏輯單元測試
✅ Repository 資料存取單元測試
⚠️ 開發時間較長
2️⃣ 僅 BDD 整合測試(推薦)
✅ API 端點測試(透過 WebApplicationFactory)
✅ 涵蓋 Controller → Handler → Repository 完整流程
⚠️ 無法單獨測試業務邏輯
3️⃣ 僅單元測試
✅ Handler 業務邏輯單元測試
✅ Repository 資料存取單元測試
⚠️ 無 API 端點測試
4️⃣ 暫不實作測試
⚠️ 快速原型、POC 驗證
❌ 無法保證程式碼品質
請提供需要測試的情境(可多選):
☑️ Happy Path(成功路徑)
- 正常輸入,預期成功回應
☑️ 驗證失敗情境
- 必填欄位缺失
- 格式驗證失敗(Email、電話格式)
- 業務規則驗證失敗
☑️ 業務錯誤情境
- 重複資料(如 Email 已存在)
- 資料不存在(如查無會員)
- 狀態不符(如訂單已完成無法取消)
☑️ 邊界條件
- 空字串、null 值
- 最大/最小值
- 特殊字元處理
☑️ 分頁與排序
- Offset 分頁測試
- Cursor 分頁測試
- 排序欄位測試
請選擇測試資料準備策略:
1️⃣ 使用 Docker 容器(推薦)
✅ SQL Server Testcontainer
✅ Redis Testcontainer
✅ MockServer Testcontainer(模擬外部 API)
⚠️ 需要 Docker 環境
2️⃣ 使用固定測試資料(Seed Data)
✅ 每次測試前載入固定資料
✅ 測試結果可預期
⚠️ 需要手動維護種子資料(DB/Scripts/*.sql)
3️⃣ 動態產生測試資料
✅ 每次測試動態產生資料
✅ 避免資料衝突
⚠️ 測試結果較不穩定
測試資料清理策略:
☑️ 每個情境前清空所有資料(推薦)
☐ 每個情境後清空資料
☐ 所有測試結束後清空
請選擇測試替身策略:
1️⃣ Docker 優先(推薦)
✅ 優先使用 Testcontainers(資料庫、Redis、MockServer)
✅ 僅在無法使用 Docker 時才用 Mock(如第三方 API)
✅ 真實環境,問題容易重現
2️⃣ Mock 優先
⚠️ 使用 Moq/NSubstitute 模擬所有依賴
⚠️ 測試速度快,但與真實環境有差異
❌ 不推薦用於 API 整合測試
是否需要模擬外部 API?
1️⃣ 是,需要模擬外部 API
- 使用 MockServer 容器
- 可設定回應內容、狀態碼、延遲時間
- 範例:第三方支付 API、簡訊發送 API、Email 服務
2️⃣ 否,不需要外部 API
- 此功能不涉及外部 API 呼叫
錯誤訊息:
⚠️ 警告:測試專案已存在
偵測到以下測試專案(包含 "test" 關鍵字的 .csproj 檔案):
- src/be/JobBank1111.Job.IntegrationTest/JobBank1111.Job.IntegrationTest.csproj
- src/be/JobBank1111.Job.Test/JobBank1111.Job.Test.csproj
處理方式:
請選擇:
1️⃣ 使用現有測試專案(推薦)
2️⃣ 建立新的測試專案(需提供不同名稱)
3️⃣ 取消操作
請選擇:
錯誤訊息:
❌ 錯誤:建立測試專案失敗
錯誤訊息:The template "xUnit Test Project" could not be found.
處理方式:
# 確認 .NET SDK 已安裝
dotnet --version
# 重新安裝 xUnit 範本
dotnet new --install Microsoft.DotNet.Test.ProjectTemplates.8.0
# 重試建立專案
dotnet new xunit -n {ProjectName}.IntegrationTest
錯誤訊息:
❌ 錯誤:安裝 NuGet 套件失敗
套件:Testcontainers 3.10.0
錯誤:Unable to find package 'Testcontainers' with version (>= 3.10.0)
處理方式:
# 清除 NuGet 快取
dotnet nuget locals all --clear
# 重試安裝
dotnet add package Testcontainers --version 3.10.0
# 或使用最新版本
dotnet add package Testcontainers
錯誤訊息:
❌ 錯誤:Docker 容器啟動失敗
容器:mcr.microsoft.com/mssql/server:2022-latest
錯誤:Docker daemon is not running
處理方式:
請確認:
1️⃣ Docker Desktop 是否已啟動?
- Windows: 檢查系統匣是否有 Docker 圖示
- 執行: docker --version
2️⃣ Docker daemon 是否正在執行?
- 執行: docker ps
3️⃣ 是否有足夠的系統資源?
- Docker Desktop 設定 > Resources
- 建議:至少 4GB RAM、2 CPU
錯誤訊息:
⚠️ 警告:測試專案結構不完整
缺少以下核心檔案:
- BaseStep.cs
- TestServer.cs
處理方式:
請選擇:
1️⃣ 自動補齊缺少的檔案(推薦)
2️⃣ 手動建立檔案
3️⃣ 重新建立測試專案
請選擇:
✅ 專案檔案檢查
# 檢查專案是否存在
Test-Path "src/be/{ProjectName}.IntegrationTest/{ProjectName}.IntegrationTest.csproj"
# 檢查是否已加入解決方案
dotnet sln list | Select-String "IntegrationTest"
✅ NuGet 套件檢查
# 列出已安裝的套件
dotnet list src/be/{ProjectName}.IntegrationTest package
# 應包含以下關鍵套件:
# - xUnit
# - Reqnroll.xUnit
# - Testcontainers
# - Microsoft.AspNetCore.Mvc.Testing
✅ 專案結構檢查
# 檢查核心檔案是否存在
Test-Path "src/be/{ProjectName}.IntegrationTest/BaseStep.cs"
Test-Path "src/be/{ProjectName}.IntegrationTest/TestServer.cs"
Test-Path "src/be/{ProjectName}.IntegrationTest/_01_Demo/Demo.feature"
✅ 測試執行檢查
# 執行測試驗證環境
task test-integration
# 或
dotnet test src/be/{ProjectName}.IntegrationTest
請參考檔案(透過 FileResolver 取得):JobBank1111.Job.IntegrationTest/_01_Demo/飯粒.feature
Feature: 會員管理 API
作為系統管理員
我想要管理會員資料
以便維護系統使用者
Background:
Given 初始化測試伺服器
| Now | UserId |
| 2000-01-01T00:00:00+00:00 | admin |
Given 調用端已準備 Header 參數
| x-trace-id |
| TEST-001 |
Scenario: 成功建立新會員
Given 調用端已準備 Body 參數(Json)
"""
{
"email": "user@example.com",
"name": "張三",
"age": 25
}
"""
When 調用端發送 "POST" 請求至 "api/v1/members"
Then 預期得到 HttpStatusCode 為 "201"
Then 預期回傳內容中路徑 "$.id" 的"字串等於" "1"
Then 預期資料庫已存在 Member 資料為
| Email | Name | Age |
| user@example.com | 張三 | 25 |
Given 初始化測試伺服器
| Now | UserId |
| 2000-01-01T00:00:00+00:00 | admin |
Given 資料庫已存在 Member 資料
| Id | Email | Name | Age |
| 1 | user@example.com | 張三 | 25 |
Given 調用端已準備 Header 參數
| x-trace-id | content-type |
| TEST-001 | application/json |
Given 調用端已準備 Query 參數
| pageSize | pageIndex |
| 10 | 0 |
Given 調用端已準備 Body 參數(Json)
"""
{
"email": "user@example.com",
"name": "張三"
}
"""
Given 建立假端點,HttpMethod = "POST",URL = "/external/api/notify",StatusCode = "200",ResponseContent =
"""
{
"success": true
}
"""
When 調用端發送 "POST" 請求至 "api/v1/members"
When 調用端發送 "GET" 請求至 "api/v1/members/123"
Then 預期得到 HttpStatusCode 為 "200"
Then 預期得到 HttpStatusCode 為 "201"
Then 預期得到 HttpStatusCode 為 "400"
Then 預期得到 HttpStatusCode 為 "404"
Then 預期得到 HttpStatusCode 為 "409"
Then 預期回傳內容中路徑 "$.id" 的"字串等於" "1"
Then 預期回傳內容中路徑 "$.age" 的"數值等於" "25"
Then 預期回傳內容中路徑 "$.isActive" 的"布林值等於" "true"
Then 預期回傳內容中路徑 "$.createdAt" 的"時間等於" "2000-01-01T00:00:00+00:00"
Then 預期回傳內容為
"""
{
"id": "1",
"email": "user@example.com",
"name": "張三"
}
"""
Then 預期資料庫已存在 Member 資料為
| Id | Email | Name | Age |
| 1 | user@example.com | 張三 | 25 |
# 執行所有整合測試
task test-integration
# 執行特定 Feature
dotnet test --filter "FullyQualifiedName~會員管理"
# 執行特定 Scenario
dotnet test --filter "FullyQualifiedName~成功建立新會員"
JobBank1111.Job.IntegrationTest/
├── BaseStep.cs # 通用測試步驟基底類別
├── TestServer.cs # WebApplicationFactory 測試伺服器
├── TestAssistant.cs # 測試輔助工具
├── ScenarioContextExtension.cs # 情境上下文擴充
├── DbContextExtensions.cs # 資料庫測試擴充
├── ServiceCollectionExtension.cs # DI 容器擴充
├── _01_Demo/
│ ├── 飯粒.feature # BDD 情境定義範例
│ ├── 飯粒Step.cs # 自訂測試步驟範例
│ └── TestController.cs # 測試用 Controller
└── DB/Scripts/ # 種子資料(選用)
JobBank1111.Testing.Common/
├── TestContainerFactory.cs # Docker 容器工廠
├── UrlBuilder.cs # URL 建構工具
├── SqlServerGenerateScript.cs # SQL Server 清空資料腳本
├── NpgsqlGenerateScript.cs # PostgreSQL 清空資料腳本
└── MockServer/
├── MockedServerAssistant.cs # MockServer 輔助工具
└── Contracts/ # MockServer 請求/回應模型
❌ 錯誤:無法啟動 SQL Server 容器
建議:
1. 確認 Docker Desktop 已啟動
2. 檢查環境變數 DOCKER_HOST=tcp://127.0.0.1:2375
3. 確認 Docker 有足夠資源(記憶體 >= 4GB、CPU >= 2 核心)
4. 查看 Docker 日誌:docker logs <container_id>
❌ 錯誤:測試並行執行時資料衝突
建議:
1. 確認已設定 DisableTestParallelization = true
2. 檢查 BaseStep.cs 的 CollectionDefinition 設定
3. 每個測試使用獨立的資料(不同 ID、Email)
❌ 錯誤:預期與實際 JSON 不符
建議:
1. 檢查 JSON 格式(空白、換行、大小寫)
2. 使用 JsonPath 驗證部分欄位而非完整比對
3. 注意日期時間格式與時區(統一使用 UTC)
api-development - API 開發流程error-handling - Result Pattern 錯誤處理handler - Handler 業務邏輯實作ef-core - EF Core 資料存取bdd-testing - BDD 基礎測試概念testing-strategy - 測試策略規劃專家feature-development - 完整功能開發流程(包含測試)以下參考檔案可通過 FileResolver 取得。
JobBank1111.Job.IntegrationTest/BaseStep.cs
node .claude/skills/shared/FileResolver.js get-content JobBank1111.Job.IntegrationTest/BaseStep.csJobBank1111.Job.IntegrationTest/TestServer.cs
node .claude/skills/shared/FileResolver.js get-content JobBank1111.Job.IntegrationTest/TestServer.csJobBank1111.Job.IntegrationTest/ScenarioContextExtension.cs
node .claude/skills/shared/FileResolver.js get-content JobBank1111.Job.IntegrationTest/ScenarioContextExtension.csJobBank1111.Job.IntegrationTest/DbContextExtensions.cs
node .claude/skills/shared/FileResolver.js get-content JobBank1111.Job.IntegrationTest/DbContextExtensions.csJobBank1111.Testing.Common/TestContainerFactory.cs
node .claude/skills/shared/FileResolver.js get-content JobBank1111.Testing.Common/TestContainerFactory.csJobBank1111.Testing.Common/MockServer/MockedServerAssistant.cs
node .claude/skills/shared/FileResolver.js get-content JobBank1111.Testing.Common/MockServer/MockedServerAssistant.csJobBank1111.Job.IntegrationTest/_01_Demo/飯粒.feature
node .claude/skills/shared/FileResolver.js get-content JobBank1111.Job.IntegrationTest/_01_Demo/飯粒.featureJobBank1111.Job.IntegrationTest/_01_Demo/飯粒Step.cs
node .claude/skills/shared/FileResolver.js get-content JobBank1111.Job.IntegrationTest/_01_Demo/飯粒Step.cs所有上述參考檔案都通過 FileResolver 自動取得。如果您:
# 取得檔案內容(本地優先,自動從 GitHub 下載並快取)
node .claude/skills/shared/FileResolver.js get-content <path>
# 檢查本地檔案路徑(如果存在)
node .claude/skills/shared/FileResolver.js get-path <path>
# 檢視 GitHub Raw URL
node .claude/skills/shared/FileResolver.js get-github-url <path>
# 清空快取
node .claude/skills/shared/FileResolver.js clear-cache
# 列出所有快取檔案
node .claude/skills/shared/FileResolver.js list-cache