使用 dotnet test 與 xUnit 為 .NET Core 中的 C# 進行單元測試

本教學課程說明如何建立包含單元測試專案和原始程式碼專案的方案。 若要遵循使用預先建立之解決方案的教學課程,請 參閱或下載範例程式碼。 如需下載指示,請參閱範例和教學課程

建立方案

在本節中,會建立包含來源和測試專案的方案。 完成的解決方案具有下列目錄結構:

/unit-testing-using-dotnet-test
    unit-testing-using-dotnet-test.sln
    /PrimeService
        PrimeService.cs
        PrimeService.csproj
    /PrimeService.Tests
        PrimeService_IsPrimeShould.cs
        PrimeServiceTests.csproj

下列指示提供建立測試解決方案的步驟。 請參閱 建立測試解決方案的命令 ,以取得在一個步驟中建立測試解決方案的指示。

  • 開啟 Shell 視窗。

  • 執行以下命令:

    dotnet new sln -o unit-testing-using-dotnet-test
    

    dotnet new sln 命令會 dotnet new sln 目錄,在單元測試中建立新的解決方案。

  • 將目錄變更為 單元測試-使用-dotnet-測試 資料夾。

  • 執行以下命令:

    dotnet new classlib -o PrimeService
    

    dotnet new classlib 命令會在 dotnet new classlib 資料夾中建立新的類別庫專案。 新的類別庫將包含要測試的程式碼。

  • Class1.cs 重新命名為 PrimeService.cs

  • 以下列程式碼取代 >primeservice 中的程式碼:

    using System;
    
    namespace Prime.Services
    {
        public class PrimeService
        {
            public bool IsPrime(int candidate)
            {
                throw new NotImplementedException("Not implemented.");
            }
        }
    }
    
  • 上述程式碼:

    • NotImplementedException擲回,並顯示訊息,指出未執行此訊息。
    • 稍後會在本教學課程中更新。
  • 在 [ 單元測試-使用-dotnet-測試 ] 目錄中,執行下列命令以將類別庫專案新增至方案:

    dotnet sln add ./PrimeService/PrimeService.csproj
    
  • 藉由執行下列命令來建立 >primeservice 測試 專案:

    dotnet new xunit -o PrimeService.Tests
    
  • 上述命令會:

    • >primeservice. 測試目錄中建立>primeservice專案。 測試專案會使用 xUnit 做為測試程式庫。
    • 將下列 <PackageReference /> 元素新增至專案檔,以設定測試執行器:
      • Microsoft.NET.Test.Sdk
      • xunit
      • xunit.runner.visualstudio
      • coverlet.collector
  • 藉由執行下列命令,將測試專案新增至方案檔:

    dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj
    
  • PrimeService將類別庫新增為 >primeservice 的相依性PrimeService專案:

    dotnet add ./PrimeService.Tests/PrimeService.Tests.csproj reference ./PrimeService/PrimeService.csproj  
    

用來建立解決方案的命令

本節摘要說明上一節中的所有命令。 如果您已完成上一節中的步驟,請略過本節。

下列命令會在 windows 電腦上建立測試解決方案。 針對 macOS 和 Unix,將命令更新 ren 為的作業系統版本 ren ,以重新命名檔案:

dotnet new sln -o unit-testing-using-dotnet-test
cd unit-testing-using-dotnet-test
dotnet new classlib -o PrimeService
ren .\PrimeService\Class1.cs PrimeService.cs
dotnet sln add ./PrimeService/PrimeService.csproj
dotnet new xunit -o PrimeService.Tests
dotnet add ./PrimeService.Tests/PrimeService.Tests.csproj reference ./PrimeService/PrimeService.csproj
dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj

請依照上一節中的「以下列程式碼取代 >primeservice 中的程式碼」的指示進行。

建立測試

測試導向開發 (TDD) 的常用方法是在執行目的程式代碼之前撰寫測試。 本教學課程使用 TDD 方法。 方法是可呼叫的 IsPrime ,但不會執行。 測試呼叫 IsPrime 失敗。 使用 TDD 時,會寫入已知失敗的測試。 目的程式代碼會更新以進行測試。 您可以重複此方法,撰寫失敗的測試,然後更新要通過的目的程式代碼。

更新 >primeservice。測試 專案:

  • 刪除 >primeservice. 測試/UnitTest1 .cs
  • 建立 >primeservice 測試/PrimeService_IsPrimeShould .cs 檔案。
  • 以下列程式碼取代 PrimeService_IsPrimeShould 中的程式碼:
using Xunit;
using Prime.Services;

namespace Prime.UnitTests.Services
{
    public class PrimeService_IsPrimeShould
    {
        [Fact]
        public void IsPrime_InputIs1_ReturnFalse()
        {
            var primeService = new PrimeService();
            bool result = primeService.IsPrime(1);

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

[Fact]屬性宣告由測試執行器執行的測試方法。 在 [ >primeservice ] 資料夾中,執行 Dotnet test命令會建立兩個專案,並執行測試。 XUnit 測試執行器包含執行測試的程式進入點。 dotnet test 使用單元測試專案啟動測試執行器。

測試失敗,因為 IsPrime 尚未執行。 使用 TDD 方法,只寫入足夠的程式碼,使此測試通過。 以下列程式碼更新 IsPrime

public bool IsPrime(int candidate)
{
    if (candidate == 1)
    {
        return false;
    }
    throw new NotImplementedException("Not fully implemented.");
}

執行 dotnet test。 測試會成功。

新增更多測試

為0和-1 新增質數測試。 您可以複製在上一個步驟中建立的測試,並建立下列程式碼的複本來測試0和-1。 但請不要這麼做,因為有更好的方法。

var primeService = new PrimeService();
bool result = primeService.IsPrime(1);

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

只有在參數變更時複製測試程式碼會導致程式碼重複和測試膨脹。 下列 xUnit 屬性可讓您撰寫類似測試的套件:

  • [Theory] 代表執行相同程式碼但具有不同輸入引數的測試套件。
  • [InlineData] 屬性會指定這些輸入的值。

不是建立新的測試,而是套用先前的 xUnit 屬性來建立單一的理論。 將下列程式碼:

[Fact]
public void IsPrime_InputIs1_ReturnFalse()
{
    var primeService = new PrimeService();
    bool result = primeService.IsPrime(1);

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

取代為下列程式碼:

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

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

在上述程式碼中, [Theory][InlineData] 您可以測試數個小於二的值。 兩個是最小的質數。

在類別宣告之後和屬性之前 [Theory] 加入下列程式碼:

private readonly PrimeService _primeService;

public PrimeService_IsPrimeShould()
{
    _primeService = new PrimeService();
}

執行 dotnet test ,這兩個測試會失敗。 若要讓所有測試都通過,請使用下列程式碼來更新 IsPrime 方法:

public bool IsPrime(int candidate)
{
    if (candidate < 2)
    {
        return false;
    }
    throw new NotImplementedException("Not fully implemented.");
}

遵循 TDD 方法,新增更多失敗的測試,然後更新目的程式代碼。 查看 已完成的測試版本 和連結 庫的完整執行

完成 IsPrime 的方法不是測試 primality 的有效演算法。

其他資源