使用 MSTest 和 .NET 進行 C# 單元測試

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

本文旨在說明如何測試 .NET Core 專案。 如果您要測試 ASP.NET Core 專案,請參閱 ASP.NET Core 中的整合測試 (部分機器翻譯)。

必要條件

建立來源專案

開啟 Shell 視窗。 建立名稱為 unit-testing-using-mstest 的目錄來放置解決方案。 在此新目錄中,執行 dotnet new sln 以針對類別庫與測試專案建立新方案檔。 建立 PrimeService 目錄。 下列大綱顯示到目前為止的目錄與檔案結構:

/unit-testing-using-mstest
    unit-testing-using-mstest.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-mstest 目錄。 執行 dotnet sln add 以將類別庫專案加入解決方案中:

dotnet sln add PrimeService/PrimeService.csproj

建立測試專案

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

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

PrimeService.Tests 目錄設為目前的目錄,然後使用 dotnet new mstest 建立新的專案。 dotnet new 命令會建立將 MSTest 作為測試程式庫使用的測試專案。 範本會在 PrimeServiceTests.csproj 檔案中設定 Test Runner:

<ItemGroup>
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
  <PackageReference Include="MSTest.TestAdapter" Version="2.1.1" />
  <PackageReference Include="MSTest.TestFramework" Version="2.1.1" />
  <PackageReference Include="coverlet.collector" Version="1.3.0" />
</ItemGroup>

測試專案需要其他套件來建立和執行單元測試。 上一步中的 dotnet new 新增了 MSTest SDK、MSTest 測試架構、MSTest 執行器,以及用於程式碼涵蓋範圍報告的 Coverlet。

PrimeService 類別庫新增為專案的另一個相依性。 使用 dotnet add reference 命令:

dotnet add reference ../PrimeService/PrimeService.csproj

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

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

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

變更為 unit-testing-using-mstest 目錄,然後執行 dotnet sln add

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

建立第一個測試

撰寫一個會失敗的測試,再使其通過,然後重複這個流程。 從 PrimeService.Tests 目錄移除 UnitTest1.cs,然後使用下列內容建立名為 PrimeService_IsPrimeShould.cs 的新 C# 檔案:

using Microsoft.VisualStudio.TestTools.UnitTesting;
using Prime.Services;

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

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

        [TestMethod]
        public void IsPrime_InputIs1_ReturnFalse()
        {
            bool result = _primeService.IsPrime(1);

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

TestClass 屬性代表包含單元測試的類別。 TestMethod 屬性表示方法是測試方法。

儲存此檔案並執行 dotnet test 來建置測試和類別庫,然後執行測試。 MSTest 測試執行器包含執行測試的程式進入點。 dotnet test 會使用您建立的單元測試專案來開始測試執行器。

您的測試失敗。 您尚未建立實作。 在可運作的 PrimeService 類別中撰寫最簡單的程式碼以讓此測試成功:

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

unit-testing-using-mstest 目錄中,重新執行 dotnet testdotnet test 命令會依序執行 PrimeService 專案和 PrimeService.Tests 專案的建置。 建置這兩個專案之後,它將會執行此單一測試。 測試通過。

新增更多功能

現在,您已經讓一個測試順利通過,您可以撰寫更多測試。 還有一些其他適用於質數 0、-1 的簡單案例。 您可以使用 TestMethod 屬性新增新的測試,但這段過程很快就會單調乏味。 因此,還有其他 MSTest 屬性,可讓您撰寫類似的測試套件。 測試方法可以執行相同程式碼,但有不同的輸入引數。 您可以使用 DataRow 屬性來指定這些輸入的值。

您不需要建立新測試,只要套用這兩個屬性以建立單一資料驅動測試即可。 資料驅動型測試是一種測試方法,其會測試數個低於二 (最小質數) 的值。 在 PrimeService_IsPrimeShould.cs 中新增測試方法:

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

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

執行 dotnet test,然後會有兩個測試失敗。 若要讓所有測試都能通過,請變更 PrimeService.cs 檔案中 IsPrime 方法開頭處的 if 子句:

if (candidate < 2)

繼續在主要程式庫中新增更多測試、更多理論和更多程式碼,以反覆執行。 您有測試的完成版程式庫的完整實作

您已建置好小型的程式庫和該程式庫的一組單元測試, 您已建立方案結構,因此加入新套件與測試是一般工作流程的一部分。 您已集中大部分的時間與精力以解決應用程式目標。

另請參閱