$npx -y skills add kevintsengtw/dotnet-testing-agent-skills --skill dotnet-testing-advanced-testcontainers-nosqlTestcontainers NoSQL 整合測試完整指南。當需要對 MongoDB 或 Redis 進行容器化整合測試時使用。涵蓋 MongoDB 文件操作、Redis 五種資料結構、Collection Fixture 模式。包含 BSON 序列化、索引效能測試、資料隔離策略與容器生命週期管理。 Make sure to use this skill whenever the user mentions Testcontainers MongoDB, Testcontainers Redis, NoSQL integration test, BSON
| 1 | # Testcontainers NoSQL 整合測試指南 |
| 2 | |
| 3 | ## 核心概念 |
| 4 | |
| 5 | ### NoSQL 測試的挑戰 |
| 6 | |
| 7 | NoSQL 資料庫測試與關聯式資料庫有顯著差異: |
| 8 | |
| 9 | 1. **文件模型複雜度**:MongoDB 支援巢狀物件、陣列、字典等複雜結構 |
| 10 | 2. **無固定 Schema**:需要透過測試驗證資料結構的一致性 |
| 11 | 3. **多樣化資料結構**:Redis 有五種主要資料結構,各有不同使用場景 |
| 12 | 4. **序列化處理**:BSON (MongoDB) 與 JSON (Redis) 序列化行為需要驗證 |
| 13 | |
| 14 | ### Testcontainers 優勢 |
| 15 | |
| 16 | - **真實環境模擬**:使用實際的 MongoDB 7.0 和 Redis 7.2 容器 |
| 17 | - **一致性測試**:測試結果直接反映正式環境行為 |
| 18 | - **隔離性保證**:每個測試環境完全獨立 |
| 19 | - **效能驗證**:可進行真實的索引效能測試 |
| 20 | |
| 21 | ## 環境需求 |
| 22 | |
| 23 | ### 必要套件 |
| 24 | |
| 25 | ```xml |
| 26 | <Project Sdk="Microsoft.NET.Sdk"> |
| 27 | <PropertyGroup> |
| 28 | <TargetFramework>net9.0</TargetFramework> |
| 29 | <Nullable>enable</Nullable> |
| 30 | <ImplicitUsings>enable</ImplicitUsings> |
| 31 | <IsPackable>false</IsPackable> |
| 32 | </PropertyGroup> |
| 33 | |
| 34 | <ItemGroup> |
| 35 | <!-- MongoDB 相關套件 --> |
| 36 | <PackageReference Include="MongoDB.Driver" Version="3.7.1" /> |
| 37 | <PackageReference Include="MongoDB.Bson" Version="3.7.1" /> |
| 38 | |
| 39 | <!-- Redis 相關套件 --> |
| 40 | <PackageReference Include="StackExchange.Redis" Version="2.12.8" /> |
| 41 | |
| 42 | <!-- Testcontainers --> |
| 43 | <PackageReference Include="Testcontainers" Version="4.11.0" /> |
| 44 | <PackageReference Include="Testcontainers.MongoDb" Version="4.11.0" /> |
| 45 | <PackageReference Include="Testcontainers.Redis" Version="4.11.0" /> |
| 46 | |
| 47 | <!-- 測試框架 --> |
| 48 | <PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.3.0" /> |
| 49 | <PackageReference Include="xunit" Version="2.9.3" /> |
| 50 | <PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" /> |
| 51 | <PackageReference Include="AwesomeAssertions" Version="9.4.0" /> |
| 52 | |
| 53 | <!-- JSON 序列化與時間測試 --> |
| 54 | <PackageReference Include="System.Text.Json" Version="10.0.5" /> |
| 55 | <PackageReference Include="Microsoft.Bcl.TimeProvider" Version="10.0.5" /> |
| 56 | <PackageReference Include="Microsoft.Extensions.TimeProvider.Testing" Version="10.4.0" /> |
| 57 | </ItemGroup> |
| 58 | </Project> |
| 59 | ``` |
| 60 | |
| 61 | ### 套件版本說明 |
| 62 | |
| 63 | | 套件 | 版本 | 用途 | |
| 64 | | ---------------------- | ------ | ---------------------------------- | |
| 65 | | MongoDB.Driver | 3.7.1 | MongoDB 官方驅動程式,支援最新功能 | |
| 66 | | MongoDB.Bson | 3.7.1 | BSON 序列化處理 | |
| 67 | | StackExchange.Redis | 2.12.8 | Redis 客戶端,支援 Redis 7.x | |
| 68 | | Testcontainers.MongoDb | 4.11.0 | MongoDB 容器管理 | |
| 69 | | Testcontainers.Redis | 4.11.0 | Redis 容器管理 | |
| 70 | |
| 71 | --- |
| 72 | |
| 73 | ## MongoDB 容器化測試 |
| 74 | |
| 75 | 涵蓋 MongoDB Container Fixture 建立、複雜文件模型設計(巢狀物件、陣列、字典)、BSON 序列化測試、CRUD 操作測試(含樂觀鎖定)以及索引效能與唯一性約束測試。使用 Collection Fixture 模式共享容器,節省 80% 以上的測試時間。 |
| 76 | |
| 77 | > 完整程式碼範例請參考 [MongoDB 容器化測試詳細指南](references/mongodb-testing.md) |
| 78 | |
| 79 | --- |
| 80 | |
| 81 | ## Redis 容器化測試 |
| 82 | |
| 83 | 涵蓋 Redis Container Fixture 建立、快取模型設計(CacheItem 泛型包裝器、UserSession、RecentView、LeaderboardEntry)以及 Redis 五種資料結構(String、Hash、List、Set、Sorted Set)的完整測試範例,包含 TTL 過期測試與資料隔離策略。 |
| 84 | |
| 85 | > 完整程式碼範例請參考 [Redis 容器化測試詳細指南](references/redis-testing.md) |
| 86 | |
| 87 | --- |
| 88 | |
| 89 | ## 最佳實踐 |
| 90 | |
| 91 | ### 1. Collection Fixture 模式 |
| 92 | |
| 93 | 使用 Collection Fixture 共享容器,避免每個測試重啟容器: |
| 94 | |
| 95 | ```csharp |
| 96 | // 定義集合 |
| 97 | [CollectionDefinition("MongoDb Collection")] |
| 98 | public class MongoDbCollectionFixture : ICollectionFixture<MongoDbContainerFixture> { } |
| 99 | |
| 100 | // 使用集合 |
| 101 | [Collection("MongoDb Collection")] |
| 102 | public class MyMongoTests |
| 103 | { |
| 104 | public MyMongoTests(MongoDbContainerFixture fixture) |
| 105 | { |
| 106 | // 使用共享的容器 |
| 107 | } |
| 108 | } |
| 109 | ``` |
| 110 | |
| 111 | ### 2. 資料隔離策略 |
| 112 | |
| 113 | 確保測試間不互相干擾: |
| 114 | |
| 115 | ```csharp |
| 116 | // MongoDB:使用唯一的 Email/Username |
| 117 | var user = new UserDocument |
| 118 | { |
| 119 | Username = $"testuser_{Guid.NewGuid():N}", |
| 120 | Email = $"test_{Guid.NewGuid():N}@example.com" |
| 121 | }; |
| 122 | |
| 123 | // Redis:使用唯一的 Key 前綴 |
| 124 | var testId = Guid.NewGuid().ToString("N")[..8]; |
| 125 | var key = $"test:{testId}:mykey"; |
| 126 | ``` |
| 127 | |
| 128 | ### 3. 清理策略 |
| 129 | |
| 130 | ```csharp |
| 131 | // MongoDB:測試後清理 |
| 132 | await fixture.ClearDatabaseAsync(); |
| 133 | |
| 134 | // Redis:使用 KeyDelete 而非 FLUSHDB(避免權限問題) |
| 135 | var keys = server.Keys(database.Database); |
| 136 | if (keys.Any()) |
| 137 | { |
| 138 | await database.KeyDeleteAsync(keys.ToArray()); |
| 139 | } |
| 140 | ``` |
| 141 | |
| 142 | ### 4. 效能考量 |
| 143 | |
| 144 | | 策略 | 說明 | |
| 145 | | ------------------ | -------------------------------------------- | |
| 146 | | Collection Fixture | 容器只啟動一次,節省 80%+ 時間 | |
| 147 | | 資料隔離 | 使用唯一 Key/ID 而非清空資料庫 | |
| 148 | | 批次操作 | 使用 InsertManyAsync、SetMultipleStringAsync | |
| 149 | | 索引建立 | 在 Fixture 初始化時建立索引 | |
| 150 | |
| 151 | --- |
| 152 | |
| 153 | ## 常見問題 |
| 154 | |
| 155 | ### Redis FLUSHDB 權限問題 |
| 156 | |
| 157 | 某些 Redis 容器映像檔預設不啟用 admin 模式: |
| 158 | |
| 159 | ```csharp |
| 160 | // ❌ 錯誤:可能失敗 |
| 161 | await server.FlushDatabaseAsync(); |
| 162 | |
| 163 | // ✅ 正確:使用 KeyDelete |
| 164 | var keys = server.Keys(database.Database); |
| 165 | if (keys.Any |