逐步解說:以使用時產生功能支援測試優先

本主題示範如何使用可支援測試優先開發的使用時產生功能。

「測試優先開發」(Test-First Development) 是一種軟體設計方式,其中,您會先根據產品規格撰寫單元測試,然後撰寫讓測試成功所需的原始程式碼。 Visual Studio 支援測試優先開發,在您尚未定義新型別和成員就要在測試案例中參照新型別和成員時,可以先在原始程式碼中產生這些型別和成員。

Visual Studio 會在對您的工作流程造成最少干擾的情況下產生新的型別和成員。 您可以建立型別、方法、屬性、欄位或建構函式的 Stub,而不需要離開程式碼中目前的位置。 當您開啟對話方塊以指定型別產生選項時,焦點會在關閉對話方塊之後立即回到目前開啟的檔案。

[使用時產生] 功能可以與整合 Visual Studio 的測試架構搭配使用。 本主題會示範 Microsoft Unit Testing Framework。

注意事項注意事項

此逐步解說是使用 Visual Basic 或 Visual C# 開發設定所撰寫。 此逐步解說也會使用其他設定。

若要變更為建議設定,您可以使用此程序:按一下 [工具] 功能表上的 [匯入和匯出設定]。 在 [匯入和匯出設定精靈] 的第一頁上,按一下 [重設所有設定]。 按一下 [選擇預設的設定集合] 頁面上的 [Visual Basic 開發設定] 或 [Visual C# 開發設定]。

若要建立 Windows 類別庫專案和測試專案

  1. 在 Visual C# 或 Visual Basic 中,建立新的 Windows 類別庫專案。 並將它命名為 GFUDemo_VB 或 GFUDemo_CS,視您所使用的語言而定。

  2. 在 [方案總管] 中,以滑鼠右鍵按一下頂端的方案圖示,並指向 [加入],然後按一下 [新增專案]。 在 [新增專案] 對話方塊左側的 [專案類型] 窗格中,按一下 [測試]。

  3. 在 [範本] 窗格中,按一下 [測試專案],並接受預設名稱 TestProject1。 下圖顯示對話方塊出現在 Visual C# 中的樣子。 在 Visual Basic 中,這個對話方塊十分類似。

    新增專案對話方塊

    [新增測試專案] 對話方塊

  4. 按一下 [確定] 關閉 [新增專案] 對話方塊。 您現在可以準備開始撰寫測試。

若要透過單元測試產生新類別

  1. 測試專案包含 UnitTest1 檔案。 按兩下 [方案總管] 中的這個檔案,在 [程式碼編輯器] 中開啟這個檔案。 已產生測試類別和測試方法。

  2. 找到 UnitTest1 類別的宣告,並將它重新命名為 AutomobileTest。 在 C# 中,如果具有 UnitTest1() 建構函式,則請將它重新命名為 AutomobileTest()。

    注意事項注意事項

    IntelliSense 現在為 IntelliSense 陳述式完成提供兩個選項:「完成模式」(Completion Mode) 和「建議模式」(Suggestion Mode)。 在尚未定義就要使用類別和成員的情況下,請使用建議模式。 當 IntelliSense 視窗開啟時,按下 CTRL+ALT+空格鍵,即可在完成模式和建議模式間進行切換。 如需詳細資訊,請參閱列出成員。 在您於下一個步驟輸入 Automobile 時,建議模式十分有幫助。

  3. 找到 TestMethod1() 方法,並將它重新命名為 DefaultAutomobileIsInitializedCorrectly()。 在這個方法內,建立名為 Automobile 類別的新執行個體,如下圖所示。 會出現波形底線,表示編譯時期錯誤,而且會在型別名稱底下出現智慧標籤。 智慧標籤的確切位置會隨著您使用 Visual Basic 還是 Visual C# 而不同。

    Visual Basic

    Visual Basic 中的智慧標籤底線

    Visual C#

    C# 中的智慧標籤底線

  4. 將滑鼠指標置於智慧標籤上方,就會看到一則錯誤訊息,指出尚未定義 Automobile 類型。 按一下智慧標籤,或按 CTRL+. (CTRL+句點) 開啟 [使用時產生] 捷徑功能表 (如下圖所示)。

    Visual Basic

    Visual Basic 中的智慧標籤內容功能表

    Visual C#

    C# 中的智慧標籤內容功能表

  5. 您現在有兩種選擇。 您可以按一下 [產生 'Class Automobile'] 以在測試專案中建立新檔案,並在其中填入空的 Automobile 類別。 若要在目前專案的新檔案中建立含有預設存取修飾詞的新類別,這是十分快速的方式。 您也可以按一下 [產生新的型別] 開啟 [產生新的型別] 對話方塊。 提供的選項包括在現有檔案中放置類別,以及將檔案加入至其他方案。

    按一下 [產生新的型別] 開啟 [產生新的型別] 對話方塊 (如下圖所示)。 按一下 [專案] 清單中的 [GFUDemo_VB] 或 [GFUDemo_CS],指示 Visual Studio 將檔案加入至原始程式碼專案,而不是測試專案。

    產生新的型別對話方塊

    [產生新的型別] 對話方塊

  6. 按一下 [確定] 關閉對話方塊,並建立新的檔案。

  7. 在 [方案總管] 中,查看 GFUDemo_VB 或 GFUDemo_CS 專案節點,確認新的 Automobile.vb 或 Automobile.cs 檔案已存在。 在 [程式碼編輯器] 中,焦點還是在 AutomobileTest.DefaultAutomobileIsInitializedCorrectly 中。 您可以在干擾最少的情況下繼續撰寫測試。

若要產生屬性 Stub

  • 假設產品規格指出 Automobile 類別有兩個公用屬性:Model 和 TopSpeed。 預設建構函式必須使用預設值 "Not specified" 和 -1 初始化這些屬性。 下列單元測試會確認預設建構函式將屬性設為其正確預設值。

    請將下列程式碼加入至 DefaultAutomobileIsInitializedCorrectly。

    Assert.IsTrue((myAuto.Model = "Not specified") And (myAuto.TopSpeed = -1))
    
    Assert.IsTrue((myAuto.Model == "Not specified") && (myAuto.TopSpeed == -1));
    

    程式碼在 Automobile 上參照兩個未定義的屬性,因此會出現智慧標籤。 請按一下 Model 的智慧標籤,然後按一下 [產生屬性 Stub]。 也請產生 TopSpeed 屬性的屬性 Stub。

    在 Automobile 類別,會透過內容正確地推論出新屬性的型別。

    下圖顯示智慧標籤捷徑功能表。

    Visual Basic

    Visual Basic 中的產生屬性內容功能表

    Visual C#

    C# 中的產生屬性內容功能表

若要尋找原始程式碼

  • 使用 [巡覽至] 功能巡覽至 Automobile.cs 或 Automobile.vb 原始程式碼檔,確認已產生新屬性。

    [巡覽至] 功能可讓您快速輸入文字字串 (例如型別名稱或名稱的一部分),然後按一下結果清單中的項目跳至想要的位置。

    在 [程式碼編輯器] 內按一下,並按 CTRL+, (CTRL+逗點),開啟 [巡覽至] 對話方塊。 在文字方塊中,輸入 automobile。 按一下清單中的 [Automobile] 類別,然後按一下 [確定]。

    下圖顯示 [巡覽至] 視窗。

    巡覽至視窗

    [巡覽至] 對話方塊

若要產生新建構函式的 Stub

  1. 使用這種測試方法,您會產生建構函式 Stub,用以初始化 Model 和 TopSpeed 屬性,使其具有您指定的值。 稍後,您將加入其他程式碼來完成測試。 請將下列其他測試方法加入至 AutomobileTest 類別。

    <TestMethod()> Public Sub AutomobileWithModelNameCanStart()
        Dim model As String = "Contoso"
        Dim topSpeed As Integer = 199
        Dim myAuto As New Automobile(model, topSpeed)
    End Sub
    
    [TestMethod]
    public void AutomobileWithModelNameCanStart()
    {
        string model = "Contoso";
        int topSpeed = 199;
        Automobile myAuto = new Automobile(model, topSpeed);
    }
    
  2. 請按一下新類別建構函式底下的智慧標籤,然後按一下 [產生建構函式 Stub]。 在 Automobile 類別檔中,請注意,新的建構函式已檢查在建構函式呼叫中使用的本機變數名稱,發現屬性的名稱與 Automobile 類別中的項目同名,並在建構函式主體內提供程式碼以將引數值儲存至 Model 和 TopSpeed 屬性中 (在 Visual Basic 中,新建構函式中的 _model 和 _topSpeed 欄位是 Model 和 TopSpeed 屬性的隱含定義之支援欄位)。

  3. 在您產生新的建構函式之後,會在 DefaultAutomobileIsInitializedCorrectly 的預設建構函式呼叫底下出現波形底線。 錯誤訊息指出 Automobile 類別沒有採用零引數的建構函式。 若要產生沒有參數的明確預設建構函式,請按一下智慧標籤,然後按一下 [產生建構函式 Stub]。

若要產生方法的 Stub

  1. 假設規格指出新的 Automobile 在其 Model 和 TopSpeed 屬性設為預設值以外的值時,可以進入 [執行中] 狀態。 將下列各行加入至 AutomobileWithModelNameCanStart 方法。

    myAuto.Start()
    Assert.IsTrue(myAuto.IsRunning = True)
    
    myAuto.Start();
    Assert.IsTrue(myAuto.IsRunning == true);
    
  2. 按一下 myAuto.Start 方法呼叫的智慧標籤,然後按一下 [產生方法 Stub]。

  3. 按一下 IsRunning 屬性的智慧標籤,然後按一下 [產生屬性 Stub]。 Automobile 類別現在包含下列程式碼。

    Public Class Automobile
        Sub New(ByVal model As String, ByVal topSpeed As Integer)
            _model = model
            _topSpeed = topSpeed
        End Sub
        Sub New()
            ' TODO: Complete member initialization 
        End Sub
    
        Property Model() As String
        Property TopSpeed As Integer
        Property IsRunning As Boolean
        Sub Start()
            Throw New NotImplementedException
        End Sub
    End Class
    
    public class Automobile
    {
        public string Model { get; set; }
        public int TopSpeed { get; set; }
    
        public Automobile(string model, int topSpeed)
        {
            this.Model = model;
            this.TopSpeed = topSpeed;
        }
    
        public Automobile()
        {
            // TODO: Complete member initialization
        }
    
        public void Start()
        {
            throw new NotImplementedException();
        }
    
        public bool IsRunning { get; set; }
    }
    

若要執行測試

  1. 指向 [測試] 功能表上的 [執行],然後按一下 [方案中的所有測試]。 這個命令會在所有針對目前方案撰寫的測試架構中執行所有測試。

    在此情況下,會進行兩項測試,而且都會如預期失敗。 DefaultAutomobileIsInitializedCorrectly 測試因 Assert.IsTrue 條件傳回 False 而失敗。 AutomobileWithModelNameCanStart 測試因 Automobile 類別中的 Start 方法擲回例外狀況而失敗。

    下圖顯示 [測試結果] 視窗。

    測試結果視窗

    失敗的測試結果

  2. 在 [測試結果] 視窗中,按兩下每個測試結果列以移至每個測試失敗的位置。

    注意事項注意事項

    如果按兩下並未將您帶至程式碼中的測試失敗處,則執行下列程序就可以啟用此功能:按一下 [工具] 功能表上的 [選項],然後展開 [測試工具],並按一下 [測試執行]。 請選取 [按兩下失敗或結果不明單元測試結果會顯示測試失敗位置] 核取方塊。

若要實作原始程式碼

  1. 將下列程式碼加入至預設建構函式,讓 Model、TopSpeed 和 IsRunning 屬性全部都初始化為其正確預設值 "Not specified"、-1 和 True (true)。

    Sub New()
        Model = "Not specified"
        TopSpeed = -1
        IsRunning = True
    End Sub
    
    public Automobile()
    {
        this.Model = "Not specified";
        this.TopSpeed = -1;
        this.IsRunning = true;
    }
    
  2. 呼叫 Start 方法時,只有在 Model 或 TopSpeed 屬性設為預設值以外的值時,才應該將 IsRunning 旗標設為 true。 請從方法主體中移除 NotImplementedException,並加入下列程式碼。

    Sub Start()
        If Model <> "Not specified" Or TopSpeed <> -1 Then
            IsRunning = True
        Else
            IsRunning = False
        End If
    End Sub
    
    public void Start()
    {
        if (this.Model != "Not specified" || this.TopSpeed != -1)
            this.IsRunning = true;
        else
            this.IsRunning = false;
    }
    

若要重新執行測試

  • 指向 [測試] 功能表上的 [執行],然後按一下 [方案中的所有測試]。 這次會通過測試。 下圖顯示 [測試結果] 視窗。

    測試結果視窗

    成功的測試結果

請參閱

工作

HOW TO:搜尋物件、定義和參考 (符號)

參考

列出成員

概念

使用時產生