逐步解說:以使用時產生功能進行測試優先開發
本主題示範如何使用 Generate From Usage 功能,支援「測試先行」開發方式。
「測試先行」開發方式 (Test-first development) 這種軟體設計方法,要先根據產品規格撰寫單元測試,再撰寫測試成功所需要的原始程式碼。 Visual Studio 支援測試先行開發方式的做法是,當您第一次在測試案例中參考類型和成員時,先以原始程式碼產生新的類型和成員,再定義它們。
Visual Studio 在盡可能不中斷工作流程的情況下產生新的類型和成員。 您可以建立類型、方法、屬性、欄位或建構函式的 Stub,但不離開目前所在的程式碼位置。 當您開啟對話方塊指定類型產生選項時,焦點會在對話方塊一關閉時,立即回到目前開啟的檔案。
[使用時產生] 功能可以和整合了 Visual Studio 的測試架構一起使用。 本主題會示範 Microsoft 單元測試架構。
注意
在本文的某些 Visual Studio 使用者介面項目中,您的電腦可能會顯示不同的名稱或位置。 您使用的可能是不同版本的 Visual Studio 或不同的環境設定。 如需詳細資訊,請參閱將 IDE 個人化。
建立 Windows 類別庫專案和測試專案
在 C# 或 Visual Basic 中,建立新的 Windows 類別庫專案。 將其命名為
GFUDemo_VB
或GFUDemo_CS
,視所用語言而定。在 [方案總管] 中,以滑鼠右鍵按一下上方的方案,選擇 [新增]>[新增專案]。
建立新的單元測試專案 (.NET Framework) 專案。
在類別庫專案中新增參考
在方案總管 中,以滑鼠右鍵按一下單元測試專案下的 [參考] 項目,並選擇 [加入參考]。
在 [參考管理員] 對話方塊中,選取 [專案],然後選取類別庫專案。
選擇 [確定] 以關閉 [參考管理員] 對話方塊。
儲存您的方案。 您已準備好開始撰寫測試。
從單元測試產生新類別
測試專案包含名為 UnitTest1 的檔案。 在方案總管中按兩下這個檔案,在程式碼編輯器中開啟它。 已產生測試類別和測試方法。
找到類別
UnitTest1
的宣告,並將它重新命名為AutomobileTest
。注意
IntelliSense 提供兩種完成 IntelliSense 陳述式的方式: 完成模式 (completion mode) 和 建議模式(suggestion mode)。 當類別和成員在使用前即已定義的情況下,請使用建議模式。 當 [IntelliSense] 視窗開啟時,您可以按 Ctrl+Alt+空格鍵 切換完成模式和建議模式。 如需詳細資訊,請參閱使用 IntelliSense。 當您在下個步驟輸入
Automobile
時,建議模式非常有幫助。找到
TestMethod1()
方法並將它重新命名為DefaultAutomobileIsInitializedCorrectly()
。 在這個方法內,建立名為Automobile
的類別新執行個體,如下列螢幕擷取畫面所示。 波浪底線隨即出現,這表示發生編譯時期錯誤,如果滑鼠停留在上面,快速動作錯誤燈泡會出現在左邊界或波浪線正下方。選擇或按一下 [快速動作] 燈泡。 您會看到錯誤訊息,說明類型
Automobile
未定義。 您也會看到一些解決方案。按一下 [產生新的類型] 開啟 [產生類型] 對話方塊。 此對話方塊會提供許多選項,包括在不同的專案中產生類型。
在 [專案] 清單中,按一下 [GFUDemo_VB] 或 [GFUDemo_CS] 指示 Visual Studio 將檔案新增至類別庫專案,不是新增至測試專案。 如果尚未選取,請選擇 [建立新檔案]並將其命名為 Automobile.cs 或 Automobile.vb。
按一下 [確定] 關閉對話方塊,並建立新的檔案。
在 [方案總管] 的 GFUDemo_VB 或 GFUDemo_CS 專案節點下,確認是否有新增的 Automobile.vb 或 Automobile.cs 檔案。 在程式碼編輯器中,焦點仍在
AutomobileTest.DefaultAutomobileIsInitializedCorrectly
,這可讓您以最少的中斷繼續撰寫測試。
產生屬性虛設常式
假設產品規格規定 Automobile
類別有兩個公用屬性,名為 Model
和 TopSpeed
。 這些屬性必須由預設的建構函式以 "Not specified"
和 -1
的預設值來初始化。 以下的單元測試會驗證預設建構函式是否將屬性設定為正確的預設值。
將下列程式碼新增至
DefaultAutomobileIsInitializedCorrectly
測試方法。因為程式碼參考
Automobile
上兩個未定義的屬性,所以Model
和TopSpeed
下會顯示波浪線。 將滑鼠停留在Model
上並選擇 [快速動作] 錯誤燈泡,然後選擇 [產生屬性 'Automobile.Model']。以同樣方式產生
TopSpeed
屬性的屬性 Stub。在
Automobile
類別中,會從內容正確推斷出新屬性的類型。
產生新建構函式的虛設常式
現在我們要建立一個測試方法,產生建構函式 stub 以初始化 Model
和 TopSpeed
屬性。 稍後,您會新增更多的程式碼以完成測試。
請將下列其他測試方法加入您的
AutomobileTest
類別中。按一下紅色波浪線下的 [快速動作] 錯誤燈泡,然後按一下 [在 'Automobile' 中產生建構函式]。
請注意,在
Automobile
類別檔案中,新的建構函式已檢查建構函式呼叫中所使用的區域變數名稱,找到Automobile
類別中具有相同名稱的屬性,並提供建構函式主體的程式碼將引數值儲存在Model
和TopSpeed
屬性中。產生新的建構函式後,
DefaultAutomobileIsInitializedCorrectly
的預設建構函式呼叫下會出現波浪底線。 錯誤訊息指出Automobile
類別沒有任何建構函式採用零引數。 若要產生沒有任何參數的明確預設建構函式,請按一下 [快速動作] 錯誤燈泡,然後按一下 [在 'Automobile' 中產生建構函式]。
產生方法的虛設常式
假設規格規定,如果其 Model
和 TopSpeed
屬性設為預設值以外的值,新的 Automobile
就可以放入 IsRunning
狀態。
請將下列各行加入
AutomobileWithModelNameCanStart
方法中。按一下
myAuto.Start
方法呼叫的 [快速動作] 錯誤燈泡,然後按一下 [產生方法 'Automobile.Start']。按一下
IsRunning
屬性的 [快速動作] 燈泡,然後按一下 [產生屬性 'Automobile.IsRunning']。Automobile
類別現在包含名為Start()
的方法,和名為IsRunning
的屬性。
執行測試
在 [測試] 功能表上,選擇 [執行]>[所有測試]。
[執行]>[所有測試] 命令會執行為目前的解決方案撰寫的任何測試架構中的全部測試。 在這個案例中,會有兩個測試,而且兩個測試都應該要失敗。
DefaultAutomobileIsInitializedCorrectly
測試失敗的原因是Assert.IsTrue
條件傳回False
。AutomobileWithModelNameCanStart
測試失敗的原因是Start
類別的Automobile
方法擲回例外狀況。下圖顯示 [測試結果] 視窗。
在 [測試結果] 視窗中,在每個測試結果資料列按兩下,移至每一項測試的位置。
實作原始程式碼
將下列程式碼加入預設建構函式中,讓
Model
、TopSpeed
和IsRunning
屬性都初始化為正確的"Not specified"
、-1
和False
(C# 為false
) 預設值。呼叫
Start
方法時,它應該只有在IsRunning
或Model
屬性設為預設值以外的值時,才將TopSpeed
旗標設為 true。 從方法主體移除NotImplementedException
,並加入下列程式碼。
再次執行測試
在 [測試] 功能表中指向 [執行],然後按一下 [所有測試]。
測試這一次會成功。 下圖顯示 [測試結果] 視窗。