SKILL.md
readonlyread-only
name
csharp-tunit
description
取得 TUnit 單元測試的最佳實務,包含資料驅動測試
TUnit 最佳實務
你的目標是協助我使用 TUnit 撰寫有效的單元測試,涵蓋標準測試與資料驅動測試方法。
專案設定
- 使用獨立的測試專案,命名慣例為
[ProjectName].Tests - 參考 TUnit 套件與 TUnit.Assertions 以使用流暢的斷言
- 建立與被測試類別對應的測試類別(例如
Calculator對應CalculatorTests) - 使用 .NET SDK 測試命令:
dotnet test執行測試 - TUnit 需要 .NET 8.0 或更高版本
測試結構
- 不需要測試類別屬性(如 xUnit/NUnit)
- 測試方法使用
[Test]屬性(而非 xUnit 的[Fact]) - 遵循 Arrange-Act-Assert (AAA) 模式
- 使用
MethodName_Scenario_ExpectedBehavior模式命名測試 - 使用生命週期鉤子:
[Before(Test)]設定測試前準備,[After(Test)]測試後清理 - 使用
[Before(Class)]和[After(Class)]在類別內測試之間共享上下文 - 使用
[Before(Assembly)]和[After(Assembly)]跨測試類別共享上下文 - TUnit 支援進階生命週期鉤子,如
[Before(TestSession)]和[After(TestSession)]
標準測試
- 保持測試專注於單一行為
- 避免在一個測試方法中測試多個行為
- 使用 TUnit 的流暢斷言語法搭配
await Assert.That() - 僅包含驗證測試案例所需的斷言
- 讓測試獨立且冪等(可任意順序執行)
- 避免測試間相依(必要時使用
[DependsOn]屬性)
資料驅動測試
- 使用
[Arguments]屬性提供內聯測試資料(相當於 xUnit 的[InlineData]) - 使用
[MethodData]屬性提供方法式測試資料(相當於 xUnit 的[MemberData]) - 使用
[ClassData]屬性提供類別式測試資料 - 實作
ITestDataSource建立自訂資料來源 - 在資料驅動測試中使用有意義的參數名稱
- 同一個測試方法可套用多個
[Arguments]屬性
斷言
- 使用
await Assert.That(value).IsEqualTo(expected)進行值相等性比較 - 使用
await Assert.That(value).IsSameReferenceAs(expected)進行參考相等性比較 - 使用
await Assert.That(value).IsTrue()或await Assert.That(value).IsFalse()進行布林條件判斷 - 使用
await Assert.That(collection).Contains(item)或await Assert.That(collection).DoesNotContain(item)進行集合判斷 - 使用
await Assert.That(value).Matches(pattern)進行正規表示式比對 - 使用
await Assert.That(action).Throws<TException>()或await Assert.That(asyncAction).ThrowsAsync<TException>()測試例外狀況 - 使用
.And運算子鏈結斷言:await Assert.That(value).IsNotNull().And.IsEqualTo(expected) - 使用
.Or運算子處理替代條件:await Assert.That(value).IsEqualTo(1).Or.IsEqualTo(2) - 使用
.Within(tolerance)進行 DateTime 與數值比較(含容差) - 所有斷言皆為非同步,必須使用 await
進階功能
- 使用
[Repeat(n)]重複執行測試多次 - 使用
[Retry(n)]在失敗時自動重試 - 使用
[ParallelLimit<T>]控制平行執行限制 - 使用
[Skip("reason")]條件式跳過測試 - 使用
[DependsOn(nameof(OtherTest))]建立測試相依性 - 使用
[Timeout(milliseconds)]設定測試逾時 - 透過擴充 TUnit 的基底屬性建立自訂屬性
測試組織
- 依功能或元件分組測試
- 使用
[Category("CategoryName")]進行測試分類 - 使用
[DisplayName("Custom Test Name")]設定自訂測試名稱 - 考慮使用
TestContext進行測試診斷與資訊 - 使用條件屬性如自訂的
[WindowsOnly]進行平台特定測試
效能與平行執行
- TUnit 預設平行執行測試(不同於 xUnit 需要明確設定)
- 使用
[NotInParallel]停用特定測試的平行執行 - 使用
[ParallelLimit<T>]搭配自訂限制類別控制並行數量 - 同一類別內的測試預設依序執行
- 使用
[Repeat(n)]搭配[ParallelLimit<T>]進行負載測試情境
從 xUnit 遷移
- 將
[Fact]取代為[Test] - 將
[Theory]取代為[Test],並使用[Arguments]提供資料 - 將
[InlineData]取代為[Arguments] - 將
[MemberData]取代為[MethodData] - 將
Assert.Equal取代為await Assert.That(actual).IsEqualTo(expected) - 將
Assert.True取代為await Assert.That(condition).IsTrue() - 將
Assert.Throws<T>取代為await Assert.That(action).Throws<T>() - 將建構函式/IDisposable 取代為
[Before(Test)]/[After(Test)] - 將
IClassFixture<T>取代為[Before(Class)]/[After(Class)]
為什麼選擇 TUnit 而非 xUnit?
TUnit 提供現代化、快速且靈活的測試體驗,具備 xUnit 所沒有的進階功能,例如非同步斷言、更精細的生命週期鉤子,以及改進的資料驅動測試能力。TUnit 的流暢斷言提供更清晰且更具表達力的測試驗證,特別適合複雜的 .NET 專案。






