csharp-tunit

csharp-tunit

熱門

取得 TUnit 單元測試的最佳實務,包含資料驅動測試

3.7萬星標
4569分支
更新於 2026/7/14
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 專案。