共用方式為


教學課程:使用Visual StudioCode測試 .NET 類別庫

本教學課程示範如何將測試專案新增至方案,將單元測試自動化。

先決條件

建立單元測試專案

單元測試會在開發和發佈期間提供自動化軟體測試。 您在本教學課程中使用的測試架構是 MSTest。 MSTest 是您可以從中選擇的三個測試架構之一。 其他則是 xUnitnUnit

  1. 啟動 Visual Studio Code。

  2. 開啟您在 使用 Visual Studio Code建立 .NET 類別庫中所建立的 ClassLibraryProjects 解決方案。

  3. 從 [方案總管],選取 [新增專案],或從 [命令選擇區] 選取 [.NET:新增專案]

  4. 選取 MSTest Test Project,將它命名為「StringLibraryTest」,選取預設目錄,然後選取 建立專案

    專案範本會使用下列程式代碼建立 UnitTest1.cs 檔案:

    namespace StringLibraryTest;
    
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
        }
    }
    

    單元測試範本所建立的原始程式碼會執行下列動作:

    在叫用單元測試時,會自動執行以 [TestClass] 標記的測試類別中,以 [TestMethod] 標記的每個方法

新增專案參考

若要讓測試專案使用 StringLibrary 類別,請將 StringLibraryTest 專案中的參考新增至 StringLibrary 專案。

  1. 從 [方案總管] 右鍵單擊 'StringLibraryTest' 專案,然後選取 [新增專案參考]

  2. 選取 [StringLibrary]。

新增和執行單元測試方法

當 Visual Studio 叫用單元測試時,它會執行在以 TestClassAttribute 屬性標示的類別中每個以 TestMethodAttribute 屬性標示的方法。 當找到第一個失敗,或方法中包含的所有測試都成功時,測試方法就會結束。

最常見的測試會呼叫 Assert 類別的成員。 許多判斷提示方法至少包含兩個參數,其中一個是預期的測試結果,另一個是實際測試結果。 下表顯示一些 Assert 類別最常呼叫的方法:

Assert 方法 功能
Assert.AreEqual 驗證兩個值或物件是否相等。 如果值或物件不相等,斷言就會失敗。
Assert.AreSame 確認兩個物件變數參考相同的物件。 如果變數參考不同的物件,斷言就會失敗。
Assert.IsFalse 驗證條件 false。 如果條件為 true,則斷言會失敗。
Assert.IsNotNull 檢查物件不等於 null。 如果物件是 null,則斷言會失敗。

您也可以在測試方法中使用 Assert.ThrowsException 方法來指出預期擲回的例外狀況類型。 如果未拋出指定的例外狀況,測試就會失敗。

在測試 StringLibrary.StartsWithUpper 方法時,您想要提供以大寫字元開頭的字串數目。 您預期方法會在這些情況下傳回 true,因此您可以呼叫 Assert.IsTrue 方法。 同樣地,您想要提供一些非大寫字元開頭的字串。 您預期方法會在這些情況下傳回 false,因此您可以呼叫 Assert.IsFalse 方法。

因為連結庫方法會處理字串,所以您也想要確定它已成功處理 空字串串 (String.Emptynull 字串。 空字串是沒有字元且 Length 為 0 的字串。 null 字串是尚未初始化的字串。 您可以直接呼叫 StartsWithUpper 做為靜態方法,並傳遞單一 String 自變數。 或者,您可以在指派給 nullstring 變數上,呼叫 StartsWithUpper 做為擴充方法。

您將定義三種方法,每個方法都會針對字串陣列中的每個元素呼叫 Assert 方法。 您將選擇呼叫一個具體的函式多載,以便在測試失敗時顯示您指定的錯誤訊息。 訊息會識別造成失敗的字串。

若要建立測試方法:

  1. 開啟 StringLibraryTest/UnitTest1.cs,並以下列程式代碼取代所有程序代碼。

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using UtilityLibraries;
    
    namespace StringLibraryTest
    {
        [TestClass]
        public class UnitTest1
        {
            [TestMethod]
            public void TestStartsWithUpper()
            {
                // Tests that we expect to return true.
                string[] words = { "Alphabet", "Zebra", "ABC", "Αθήνα", "Москва" };
                foreach (var word in words)
                {
                    bool result = word.StartsWithUpper();
                    Assert.IsTrue(result,
                           string.Format("Expected for '{0}': true; Actual: {1}",
                                         word, result));
                }
            }
    
            [TestMethod]
            public void TestDoesNotStartWithUpper()
            {
                // Tests that we expect to return false.
                string[] words = { "alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                                   "1234", ".", ";", " " };
                foreach (var word in words)
                {
                    bool result = word.StartsWithUpper();
                    Assert.IsFalse(result,
                           string.Format("Expected for '{0}': false; Actual: {1}",
                                         word, result));
                }
            }
    
            [TestMethod]
            public void DirectCallWithNullOrEmpty()
            {
                // Tests that we expect to return false.
                string?[] words = { string.Empty, null };
                foreach (var word in words)
                {
                    bool result = StringLibrary.StartsWithUpper(word);
                    Assert.IsFalse(result,
                           string.Format("Expected for '{0}': false; Actual: {1}",
                                         word == null ? "<null>" : word, result));
                }
            }
        }
    }
    

    TestStartsWithUpper 方法中大寫字元的測試包括希臘大寫字母 Α (U+0391)和西里爾大寫字母 М (U+041C)。 TestDoesNotStartWithUpper 方法中小寫字元的測試包括希臘小字母 Alpha (U+03B1) 和斯拉夫小字母 Ghe (U+0433)。

  2. 儲存您的變更。

建置並執行您的測試

  1. 在 [方案總管]中,以滑鼠右鍵按兩下方案,然後選取 [建置],或從 [命令選擇區] 選取 [.NET:建置]。

  2. 選擇 [測試] 視窗,選擇 [執行測試],或從 [命令選擇區] 選擇 [測試:執行所有測試]。

    Visual Studio Code Test Explorer

處理測試失敗

如果您正在進行測試驅動開發(TDD),您會先撰寫測試,並且第一次執行時會失敗。 然後將程式代碼新增至讓測試成功的應用程式。 在本教學課程中,您已在撰寫驗證的應用程式程式代碼之後建立測試,因此您沒看到測試失敗。 若要驗證測試在預期中失敗時確實失敗,請在測試輸入中加入無效的值。

  1. 修改 TestDoesNotStartWithUpper 方法中的 words 陣列,以包含字串 “Error”。

    string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " };
    
  2. 在編輯器中點擊測試旁的綠色圖示來運行測試。

    輸出會顯示測試失敗,並提供失敗測試的錯誤訊息:「Assert.IsFalse 失敗。 預期 'Error':false;實際:True。 由於失敗,陣列中「Error」之後的所有字串都沒有被測試。

    Visual Studio Code 測試失敗

  3. 拿掉您在步驟中新增的字串 “Error”。

  4. 重新執行測試和測試通過。

測試程式庫的發行版本

現在執行連結庫的偵錯組建時,測試都已通過,接下來再針對連結庫的發行組建執行測試一次。 許多因素,包括編譯程式優化,可能會在偵錯版本和發行版本之間產生不同的行為。

  1. 使用發行組建組態執行測試:

    dotnet test StringLibraryTest/StringLibraryTest.csproj --configuration Release
    

    測試通過了。

偵錯測試

如果您正在使用 Visual Studio Code 作為 IDE,您可以使用在 中展示的相同方法——使用 Visual Studio Code 偵錯 .NET 控制台應用程式—— 將其應用於使用單元測試專案進行的程式代碼偵錯。 不要啟動 ShowCase 應用程式專案,請開啟 StringLibraryTest/UnitTest1.cs,然後在目前檔案中選取 偵錯測試, 行 7 到 8 之間。 如果您找不到它,請按 Ctrl+Shift+P 開啟命令選擇區,然後輸入 重載視窗

Visual Studio Code 會使用附加的調試程序啟動測試專案。 執行會在您新增到測試專案或底層程式庫代碼中的任何斷點中止。

其他資源

  • .NET 中的 單元測試

後續步驟

在本教學課程中,您會單元測試類別庫。 您可以將連結庫發佈至 NuGet 做為套件,讓其他人可以使用連結庫。 若要瞭解如何,請遵循 NuGet 教學課程:

如果您將連結庫發佈為 NuGet 套件,其他人可以安裝並使用它。 若要瞭解如何,請遵循 NuGet 教學課程:

程式庫不需要以套件的形式散發。 它可以與使用它的控制台應用程式搭配使用。 若要瞭解如何發佈主控台應用程式,請參閱本系列先前的教學課程:

Visual Studio Code 延伸模組 C# 開發工具包提供更多工具來開發 C# 應用程式和連結庫: