# DramaLing.Api.Tests **版本**: 1.0 **框架**: xUnit + .NET 8 **狀態**: 階段四測試架構已建立 ✅ ## 🧪 測試架構概覽 本測試專案採用現代化的 .NET 8 測試框架,提供完整的單元測試、整合測試和端到端測試基礎設施。 ### 測試專案結構 ``` DramaLing.Api.Tests/ ├── README.md # 本文檔 - 測試架構說明 ├── TestBase.cs # 測試基類 - 提供通用測試設施 ├── Unit/ # 單元測試 │ ├── Services/ # 服務層測試 │ │ └── JsonCacheSerializerTests.cs # 快取序列化器測試 │ ├── Controllers/ # 控制器測試 │ └── Repositories/ # Repository 測試 │ └── FlashcardRepositoryTests.cs # Flashcard Repository 測試 ├── Integration/ # 整合測試 ├── E2E/ # 端到端測試 └── TestData/ # 測試資料工廠 └── TestDataFactory.cs # 測試資料建立工具 ``` --- ## 🔧 核心測試基礎設施 ### TestBase 類別 所有單元測試的基礎類別,提供: - **InMemory 資料庫**: 使用 Entity Framework InMemory 提供者 - **依賴注入**: 完整的 DI 容器設定 - **自動清理**: 測試完成後自動清理資源 - **服務配置**: 可覆寫的服務配置方法 ```csharp public abstract class TestBase : IDisposable { protected readonly DramaLingDbContext DbContext; protected readonly ServiceProvider ServiceProvider; // 提供完整的測試環境設定 } ``` ### TestDataFactory 類別 提供便利的測試資料建立方法: ```csharp // 建立測試使用者 var user = TestDataFactory.CreateUser(); // 建立測試單字卡 var flashcard = TestDataFactory.CreateFlashcard(userId); // 建立多個測試單字卡 var flashcards = TestDataFactory.CreateFlashcards(userId, count: 5); // 建立分析快取資料 var cache = TestDataFactory.CreateAnalysisCache(sentence); ``` --- ## 📋 已實施的測試 ### 1. Repository 層測試 **FlashcardRepositoryTests** - 完整的 Repository 模式測試: - ✅ `GetByUserIdAsync_ShouldReturnUserFlashcards` - 使用者單字卡查詢 - ✅ `GetByUserIdAndFlashcardIdAsync_ShouldReturnSpecificFlashcard` - 特定單字卡查詢 - ✅ `GetByUserIdAsync_WithSearch_ShouldReturnFilteredResults` - 搜尋過濾功能 - ✅ `GetCountByUserIdAsync_ShouldReturnCorrectCount` - 計數功能測試 ### 2. 服務層測試 **JsonCacheSerializerTests** - 快取序列化服務測試: - ✅ `Serialize_ValidObject_ShouldReturnByteArray` - 物件序列化 - ✅ `Deserialize_ValidByteArray_ShouldReturnObject` - 反序列化 - ✅ `Serialize_NullObject_ShouldThrowException` - 例外處理 - ✅ `Deserialize_InvalidByteArray_ShouldReturnNull` - 錯誤處理 - ✅ `RoundTrip_ComplexObject_ShouldMaintainDataIntegrity` - 複雜物件完整性測試 --- ## 🚀 執行測試 ### 基本指令 ```bash # 執行所有測試 dotnet test # 執行特定類別測試 dotnet test --filter "ClassName=FlashcardRepositoryTests" # 執行特定測試方法 dotnet test --filter "MethodName=GetByUserIdAsync_ShouldReturnUserFlashcards" # 產生覆蓋率報告 dotnet test --collect:"XPlat Code Coverage" ``` ### 測試分類 ```bash # 執行單元測試 dotnet test --filter "Category=Unit" # 執行整合測試 dotnet test --filter "Category=Integration" # 執行端到端測試 dotnet test --filter "Category=E2E" ``` --- ## 📊 測試覆蓋狀況 ### 已覆蓋組件 | 組件類型 | 已測試項目 | 測試數量 | 狀態 | |---------|-----------|----------|------| | **Repository** | FlashcardRepository | 4 個測試 | ✅ 完成 | | **Services** | JsonCacheSerializer | 5 個測試 | ✅ 完成 | | **Controllers** | - | 0 個測試 | ⏳ 待實施 | | **Integration** | - | 0 個測試 | ⏳ 待實施 | ### 測試指標 - **單元測試數量**: 9 個 - **測試類別數量**: 2 個 - **測試基礎設施**: ✅ 完整 - **測試資料工廠**: ✅ 完整 --- ## 🔬 測試模式和最佳實務 ### AAA 模式 (Arrange-Act-Assert) 所有測試都遵循 AAA 模式: ```csharp [Fact] public async Task GetByUserIdAsync_ShouldReturnUserFlashcards() { // Arrange - 準備測試資料 var user = TestDataFactory.CreateUser(); var flashcards = TestDataFactory.CreateFlashcards(user.Id, 3); // Act - 執行被測試的動作 var result = await _repository.GetByUserIdAsync(user.Id); // Assert - 驗證結果 Assert.NotNull(result); Assert.Equal(3, result.Count()); } ``` ### 測試命名規則 - **模式**: `{MethodName}_{Scenario}_{ExpectedBehavior}` - **範例**: `GetByUserIdAsync_WithSearch_ShouldReturnFilteredResults` ### 測試資料隔離 - 每個測試使用獨立的 InMemory 資料庫 - 測試完成後自動清理資源 - 避免測試間的資料污染 --- ## 🎯 階段四完成成果 ### ✅ 已完成項目 1. **測試專案結構建立** - xUnit 測試框架設定 - 標準目錄結構 (Unit/Integration/E2E) - 必要套件配置 2. **基礎測試設施實作** - TestBase 抽象基類 - TestDataFactory 資料工廠 - 依賴注入和資料庫設定 3. **關鍵服務單元測試** - Repository 層完整測試覆蓋 - 核心服務層測試實作 - 錯誤處理和邊界情況測試 4. **測試文檔和規範** - 完整的測試指南 - 最佳實務文檔 - 執行指令說明 ### 📈 技術優勢 - **Clean Architecture 支援**: 測試架構完全符合專案的 Clean Architecture 原則 - **依賴注入整合**: 完整支援 ASP.NET Core DI 容器 - **資料隔離**: 每個測試都有獨立的資料庫環境 - **可擴展性**: 易於添加新的測試類別和測試案例 - **效能優化**: 使用 InMemory 資料庫提供快速測試執行 --- ## 📋 後續開發建議 ### 階段五建議 1. **增加整合測試** - API 端點測試 - 中間件測試 - 認證授權測試 2. **提升測試覆蓋率** - Controller 層測試 - 更多 Service 層測試 - 錯誤處理測試 3. **效能測試** - 負載測試 - 記憶體使用測試 - 資料庫查詢效能測試 4. **CI/CD 整合** - GitHub Actions 設定 - 自動化測試執行 - 覆蓋率報告生成 --- ## 🔧 開發指南 ### 新增測試的步驟 1. **選擇適當的測試類別目錄** - Unit/ - 單元測試 - Integration/ - 整合測試 - E2E/ - 端到端測試 2. **繼承適當的基類** ```csharp public class NewServiceTests : TestBase { // 測試實作 } ``` 3. **使用 TestDataFactory 建立測試資料** ```csharp var testData = TestDataFactory.CreateFlashcard(); ``` 4. **遵循 AAA 模式和命名規則** 5. **確保測試隔離和清理** --- **最後更新**: 2025-09-30 **維護者**: DramaLing 開發團隊 **測試架構版本**: 1.0 **狀態**: 階段四完成 ✅