本教學課程會逐步引導您完成建置範例解決方案的互動式體驗,以瞭解單元測試概念。
本文是關於測試 .NET Core 專案。 如果您要測試 ASP.NET Core 專案,請參閱 ASP.NET Core 中的整合測試。
Prerequisites
- .NET 10 SDK 或更新版本。
- 您偏好的文字編輯器或程式碼編輯器。
TUnit 完全建置於 Microsoft.Testing.Platform (MTP),且不支援 VSTest。 本教學使用 MTP 模式dotnet test,需 .NET 10 SDK。
建立來源專案
開啟終端機視窗。 建立一個名為 unit-testing-using-tunit 的目錄來存放解決方案。 在此新目錄內,執行下列命令,為類別庫和測試專案建立新的方案檔:
dotnet new sln
接下來,建立 PrimeService 目錄。 下列大綱顯示到目前為止的目錄和檔案結構:
/unit-testing-using-tunit
unit-testing-using-tunit.slnx
/PrimeService
將 PrimeService 設為目前的目錄,然後執行下列命令來建立來源專案:
dotnet new classlib
將 Class1.cs 重新命名為 PrimeService.cs。 您建立一個 PrimeService 類別的失敗實作:
using System;
namespace Prime.Services
{
public class PrimeService
{
public bool IsPrime(int candidate)
{
throw new NotImplementedException("Please create a test first.");
}
}
}
切換回 unit-testing-using-tunit 目錄。 執行下列命令,將類別庫專案新增至方案:
dotnet sln add PrimeService/PrimeService.csproj
建立測試專案
接下來,建立 PrimeService.Tests 目錄。 下列大綱顯示目錄結構:
/unit-testing-using-tunit
unit-testing-using-tunit.slnx
/PrimeService
Source Files
PrimeService.csproj
/PrimeService.Tests
TUnit 專案範本不包含在 .NET SDK 中。 請使用以下指令安裝:
dotnet new install TUnit.Templates
將目錄變更為 PrimeService.Tests 目錄,然後使用下列命令建立新專案:
dotnet new TUnit
Note
模板短名稱具有大小寫區分。 使用 TUnit,而不是 tunit。
dotnet new 指令會建立一個使用 TUnit 作為測試函式庫的測試專案。 產生的 PrimeService.Tests.csproj 檔案是一個可執行專案,會參考 TUnit 套件(版本號可能不同):
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="TUnit" Version="1.*" />
</ItemGroup>
該 TUnit 套件包含測試框架、斷言函式庫和 MTP 測試執行器,因此專案不需要其他測試套件。 範本還新增了範例測驗。 請刪除 PrimeService.Tests 目錄中所有 .cs 檔案和 Data 目錄,因為這個教學會用自己的測試取代它們。
現在,將 PrimeService 類別庫新增為專案的另一個相依性。 使用 dotnet reference add 命令:
dotnet reference add ../PrimeService/PrimeService.csproj
下列大綱顯示最終解決方案配置:
/unit-testing-using-tunit
unit-testing-using-tunit.slnx
/PrimeService
Source Files
PrimeService.csproj
/PrimeService.Tests
Test Source Files
PrimeService.Tests.csproj
在 unit-testing-using-tunit 目錄中執行以下指令:
dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj
設定 dotnet test 的 MTP 模式
因為 TUnit 不支援 VSTest,TUnit 必須以 MTP 模式執行。 在 unit-testing-using-tunit 目錄中,建立一個包含以下內容的 global.json 檔案:
{
"test": {
"runner": "Microsoft.Testing.Platform"
}
}
欲了解更多資訊,請參閱 dotnet 測試的 MTP 模式。
建立第一個測試
您撰寫了一個未通過的測試,使其通過,然後重複此過程。 在 PrimeService.Tests 目錄中,建立一個包含以下程式碼的 PrimeService_IsPrimeShould.cs 檔案:
namespace Prime.UnitTests.Services
{
using Prime.Services;
public class PrimeService_IsPrimeShould
{
private readonly PrimeService _primeService = new();
[Test]
public async Task IsPrime_InputIs1_ReturnFalse()
{
var result = _primeService.IsPrime(1);
await Assert.That(result).IsFalse();
}
}
}
屬性 [Test] 表示方法為測試方法。 TUnit 不需要在類別上設定屬性。 TUnit 的斷言是非同步的,因此測試方法會回傳 Task,並等待 Assert.That。 這個 TUnit 套件會為其命名空間新增全域 using 指令,因此檔案不需要它們。
Note
using Prime.Services;指令是刻意放在命名空間內的。 MTP 會在專案的根命名空間中(亦即 PrimeService.Tests)產生測試應用程式的入口點。 該命名空間會隱藏 PrimeService 類別,使位於檔案頂端的 using 指示詞無法看見它,但不會對命名空間內的 using 指示詞隱藏它。
儲存此檔案並執行 dotnet test 命令來建置測試和類別庫,並執行測試。 TUnit 測試專案包含執行測試的程式入口點。
dotnet test 用你建立的單元測試專案啟動測試應用程式。
您的測試失敗。 您尚未建立執行方案。 在可運作的 PrimeService 類別中撰寫最簡單的程式代碼,讓測試通過:
public bool IsPrime(int candidate)
{
if (candidate == 1)
{
return false;
}
throw new NotImplementedException("Please create a test first.");
}
在 unit-testing-using-tunit 目錄中,再次執行 dotnet test 。
dotnet test 命令會執行 PrimeService 項目的組建,然後執行 PrimeService.Tests 項目的組建。 建置這兩個項目之後,它會執行這個單一測試。 它通過了。
新增更多功能
現在您已經通過了一次測試,是時候寫更多了。 關於質數,有一些其他的特殊情況:0、-1。 您可以透過添加 [Test] 屬性來新增測試,但這樣做很快就會變得乏味。 TUnit 提供 [Arguments] 屬性,用於建立一套執行相同程式碼但輸入參數不同的測試套件。
不要建立新的測試,請套用此屬性來建立單一數據驅動測試。 將 IsPrime_InputIs1_ReturnFalse 方法用下列程式碼取代。 數據驅動測試是一種方法,用來測試數個小於二的數值,而二是一個最低的質數。
[Test]
[Arguments(-1)]
[Arguments(0)]
[Arguments(1)]
public async Task IsPrime_ValuesLessThan2_ReturnFalse(int value)
{
var result = _primeService.IsPrime(value);
await Assert.That(result).IsFalse();
}
執行 dotnet test,其中兩個測試會失敗。 若要讓所有測試都通過,請變更 if 檔案中 IsPrime 方法開頭的 子句:
if (candidate < 2)
持續迭代,在主函式庫中加入更多測試和程式碼。
您建置了一個小型程式庫,以及該程式庫的一組單元測試。 您也已建構解決方案,讓新增套件和測試是標準工作流程的一部分。 您大部分的時間和精力都集中在解決應用程式的目標上。