共用方式為


使用 NUnit 和 .NET Core 對 C# 進行單元測試

本教學課程會逐步引導您完成建置範例解決方案的互動式體驗,以瞭解單元測試概念。 如果您想要使用預先建置的解決方案來遵循教學課程,請在開始之前檢視或下載範例程式代碼。 如需下載指示,請參閱 範例和教學課程

本文是關於測試 .NET Core 專案。 如果您要測試 ASP.NET Core 專案,請參閱 ASP.NET Core 中的整合測試。

先決條件

建立來源專案

開啟終端機視窗。 建立名為 unit-testing-using-nunit 的目錄來保存解決方案。 在此新目錄內,執行下列命令,為類別庫和測試專案建立新的方案檔:

dotnet new sln

接下來,建立 PrimeService 目錄。 下列大綱顯示到目前為止的目錄和檔案結構:

/unit-testing-using-nunit
    unit-testing-using-nunit.sln
    /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-nunit 目錄。 執行下列命令,將類別庫專案新增至方案:

dotnet sln add PrimeService/PrimeService.csproj

建立測試專案

接下來,建立 PrimeService.Tests 目錄。 下列大綱顯示目錄結構:

/unit-testing-using-nunit
    unit-testing-using-nunit.sln
    /PrimeService
        Source Files
        PrimeService.csproj
    /PrimeService.Tests

PrimeService.Tests 目錄設為目前目錄,並使用下列命令建立新專案:

dotnet new nunit

dotnet new 命令會建立使用 NUnit 作為測試連結庫的測試專案。 產生的範本會在 PrimeService.Tests.csproj 檔案中設定測試執行器:

<ItemGroup>
  <PackageReference Include="nunit" Version="4.3.2" />
  <PackageReference Include="NUnit3TestAdapter" Version="5.0.0" />
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
  <PackageReference Include="NUnit.Analyzers" Version="4.9.2">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
  </PackageReference>
</ItemGroup>

備註

在 .NET 9 之前,產生的程式代碼可能會參考舊版的 NUnit 測試架構。 您可以使用 dotnet CLI 來更新套件。 或者,開啟 PrimeService.Tests.csproj 檔案,並將套件參考專案群組的內容取代為上述程式代碼。

測試專案需要其他套件才能建立和執行單元測試。 dotnet new上一個步驟中的命令已新增Microsoft測試 SDK、NUnit 測試架構和 NUnit 測試配接器。 現在,將 PrimeService 類別庫新增為專案的另一個相依性。 使用 dotnet reference add 命令:

dotnet reference add ../PrimeService/PrimeService.csproj

您可以在 GitHub 上的 範例存放庫 中看到整個檔案。

下列大綱顯示最終解決方案配置:

/unit-testing-using-nunit
    unit-testing-using-nunit.sln
    /PrimeService
        Source Files
        PrimeService.csproj
    /PrimeService.Tests
        Test Source Files
        PrimeService.Tests.csproj

unit-testing-using-nunit 目錄中執行下列命令:

dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj

建立第一個測試

您撰寫了一個未通過的測試,使其通過,然後重複此過程。 在 PrimeService.Tests 目錄中,將 UnitTest1.cs 檔案重新命名為 PrimeService_IsPrimeShould.cs ,並以下列程式代碼取代其整個內容:

using NUnit.Framework;
using Prime.Services;

namespace Prime.UnitTests.Services
{
    [TestFixture]
    public class PrimeService_IsPrimeShould
    {
        private PrimeService _primeService;

        [SetUp]
        public void SetUp()
        {
            _primeService = new PrimeService();
        }

        [Test]
        public void IsPrime_InputIs1_ReturnFalse()
        {
            var result = _primeService.IsPrime(1);

            Assert.That(result, Is.False, "1 should not be prime");
        }
    }
}

屬性 [TestFixture] 表示包含單元測試的類別。 屬性 [Test] 表示方法為測試方法。

儲存此檔案並執行 dotnet test 命令來建置測試和類別庫,並執行測試。 NUnit 測試執行器包含執行測試的程式進入點。 dotnet test 使用您建立的單元測試專案啟動測試執行器。

您的測試失敗。 您尚未創建實作。 在可運作的 PrimeService 類別中撰寫最簡單的程式代碼,讓測試通過:

public bool IsPrime(int candidate)
{
    if (candidate == 1)
    {
        return false;
    }
    throw new NotImplementedException("Please create a test first.");
}

unit-testing-using-nunit 目錄中,再次執行 dotnet testdotnet test 命令會執行 PrimeService 項目的組建,然後執行 PrimeService.Tests 項目的組建。 建置這兩個項目之後,它會執行這個單一測試。 它通過了。

新增更多功能

既然您已通過一次測試,現在是時候撰寫更多了。 關於質數,有一些其他的特殊情況:0、-1。 您可以透過添加 [Test] 屬性來新增測試,但這樣做很快就會變得乏味。 還有其他 NUnit 屬性可讓您撰寫一組類似的測試。 [TestCase]屬性可用來建立執行相同程序代碼但具有不同輸入自變數的測試套件。 您可以使用 [TestCase] 屬性來指定這些輸入的值。

不要建立新的測試,請套用此屬性來建立單一數據驅動測試。 數據驅動測試是一種方法,用來測試數個小於二的數值,而二是一個最低的質數。

[TestCase(-1)]
[TestCase(0)]
[TestCase(1)]
public void IsPrime_ValuesLessThan2_ReturnFalse(int value)
{
    var result = _primeService?.IsPrime(value);

    Assert.That(result, Is.False, $"{value} should not be prime");
}

執行 dotnet test,其中兩個測試會失敗。 若要讓所有測試都通過,請變更 if 檔案中 Main 方法開頭的 子句:

if (candidate < 2)

在主庫中新增更多測試、理論和代碼,以持續迭代。 您已獲得測試的完成版本 ,及函式庫 的完整實作

您已建立一個小型程式庫及其一組單元測試。 您也已建構解決方案,讓新增套件和測試是標準工作流程的一部分。 您大部分的時間和精力都集中在解決應用程式的目標上。