C# IT 紅燈實作執行器。對單一 .feature 執行完整紅燈流程: Schema Analysis → Step Template → Red Implementation(載入 Handler 實作測試)。 當 /aibdd.auto.csharp.it.control-flow 呼叫紅燈階段,或使用者說「紅燈」「red」時觸發。
寫出測試程式,確認有 Failing Test(Value Difference,非環境問題)。
dotnet build 通過環境問題 ≠ 紅燈。Value Difference = 紅燈。兩者都符合才算正式進入 Red。
| 失敗類型 | 意義 | 是否紅燈 |
|---|---|---|
| HTTP 404 Not Found | API endpoint 尚未註冊 | ✅ 紅燈(Value Difference) |
| HTTP 500 Internal | Service/Controller 拋異常 | ✅ 紅燈(未實作) |
| Assertion 失敗 | 回傳值不符預期 | ✅ 紅燈 |
NotImplementedException | Repository/Service 方法未實作 | ✅ 紅燈 |
| 編譯錯誤 | 缺 class / using | ❌ 環境問題(需先修) |
| Testcontainers 啟動失敗 | Docker 未啟動 | ❌ 環境問題 |
Step 1: Schema Analysis → 引用 /aibdd.auto.csharp.it.schema-analysis
確保 EF Core Entity / DbContext / Migration 與 spec 對齊
Step 2: Step Template → 引用 /aibdd.auto.csharp.it.step-template
為 feature 產出 SpecFlow step class 骨架(含 TODO + PendingStepException)
Step 3: Red Implementation → 對每個 TODO step:
- 讀 TODO 取得 handler type
- 引用對應 /aibdd.auto.csharp.it.handlers.{type}
- 將 PendingStepException 替換為完整測試程式碼
- 同時建立基礎設施(Models / Repositories / Services 介面)
- 執行 dotnet test 驗證紅燈(預期 HTTP 404)
引用 /aibdd.auto.csharp.it.schema-analysis。
核心任務:
引用 /aibdd.auto.csharp.it.step-template。
核心任務:
[Binding] classScenarioContextthrow new PendingStepException()對每個含 TODO 的 step definition:
/aibdd.auto.csharp.it.handlers.command)PendingStepException 替換為完整測試代碼HttpClient, AppDbContext, JwtHelper)同時建立基礎設施(若不存在):
放在 src/${ProjectName}/Models/。由 schema-analysis 建立,紅燈階段補強屬性。
// src/${ProjectName}/Repositories/ILessonProgressRepository.cs
public interface ILessonProgressRepository
{
LessonProgress? FindByUserIdAndLessonId(string userId, int lessonId);
void Save(LessonProgress entity);
}
// src/${ProjectName}/Repositories/LessonProgressRepository.cs
public class LessonProgressRepository : ILessonProgressRepository
{
private readonly AppDbContext _context;
public LessonProgressRepository(AppDbContext context) => _context = context;
public LessonProgress? FindByUserIdAndLessonId(string userId, int lessonId)
=> throw new NotImplementedException();
public void Save(LessonProgress entity)
=> throw new NotImplementedException();
}
// src/${ProjectName}/Services/ILessonProgressService.cs
public interface ILessonProgressService
{
void UpdateVideoProgress(string userId, int lessonId, int progress);
}
// src/${ProjectName}/Services/LessonProgressService.cs
public class LessonProgressService : ILessonProgressService
{
public void UpdateVideoProgress(string userId, int lessonId, int progress)
=> throw new NotImplementedException();
}
// src/${ProjectName}/DTOs/UpdateVideoProgressRequest.cs
public record UpdateVideoProgressRequest(int LessonId, int Progress);
// Program.cs
builder.Services.AddScoped<ILessonProgressRepository, LessonProgressRepository>();
builder.Services.AddScoped<ILessonProgressService, LessonProgressService>();
不要建立 Controller — 這樣測試才會收到 HTTP 404(紅燈)。
Command handler 只儲存 HttpResponseMessage 到 _ctx["LastResponse"],不做 assertion。
Request/Response 欄位名以 api.yml schemas 為 SSOT。C# 預設 camelCase(lessonId, newLeadsThisMonth)。
建立實體後,將 ID 存入 _ctx.Get<Dictionary<string, object>>("Ids")[naturalKey] = id。
基礎設施放在 production code 目錄,非 tests/ 目錄。
Red 階段只建立 interface + 空實作。
throw new NotImplementedException()失敗原因必須是 Value Difference(HTTP 404)而非環境問題。
Testcontainers PostgreSQL,不使用 In-Memory Provider(EF Core UseInMemoryDatabase 不支援複合 Key 的某些行為,不夠真實)。
Feature 的 Data Table 欄位與 api.yml / erm.dbml 欄位 1:1 對應。
HTTP 路徑從 api.yml paths 讀取,不自行編造。
docker info # Daemon 運行中
docker ps # 無殘留 Testcontainers
若 Docker 未啟動,先提示使用者啟動 Docker Desktop。
# 特定 feature(快速迭代)
dotnet test --filter "FullyQualifiedName~LessonProgress"
# 所有非 @ignore 的測試
dotnet test --filter "Category!=Ignore"
dotnet build 通過(環境 OK)PendingStepException 替換為完整測試代碼NotImplementedException)NotImplementedException)