Visual Studio 使用教程:為托管代碼創(chuàng)建和運(yùn)行單元測(cè)試(下)
Visual Studio 是功能完備的 IDE,可用于編碼、調(diào)試、測(cè)試和部署到任何平臺(tái),Visual Studio使用 .NET 開發(fā) iOS、Android 和 Web 應(yīng)用和游戲。
本文將逐步指導(dǎo)您使用用于托管代碼的Microsoft單元測(cè)試框架和Visual Studio Test Explorer創(chuàng)建,運(yùn)行和自定義一系列單元測(cè)試。您從正在開發(fā)的C#項(xiàng)目開始,創(chuàng)建執(zhí)行其代碼的測(cè)試,運(yùn)行測(cè)試并檢查結(jié)果。然后,您更改項(xiàng)目代碼并重新運(yùn)行測(cè)試。
構(gòu)建并運(yùn)行測(cè)試
- 在“生成”菜單上,選擇“生成解決方案”。
- 如果未打開“測(cè)試資源管理器”,請(qǐng)從頂部菜單欄中選擇“測(cè)試”>“ Windows”>“測(cè)試資源管理器”將其打開。
- 選擇“全部運(yùn)行”以運(yùn)行測(cè)試。
- 測(cè)試運(yùn)行時(shí),“測(cè)試資源管理器”窗口頂部的狀態(tài)欄會(huì)顯示動(dòng)畫。在測(cè)試運(yùn)行結(jié)束時(shí),如果所有測(cè)試方法均通過,則該條變?yōu)榫G色;如果任何測(cè)試失敗,則該條變?yōu)榧t色。在這種情況下,測(cè)試將失敗。
- 在“測(cè)試資源管理器”中選擇方法,以在窗口底部查看詳細(xì)信息。
修正您的代碼并重新運(yùn)行測(cè)試
測(cè)試結(jié)果包含描述失敗的消息。對(duì)于AreEqual方法,該消息顯示預(yù)期的結(jié)果和實(shí)際接收的結(jié)果。您預(yù)計(jì)余額會(huì)減少,但是取款額卻增加了。
單元測(cè)試發(fā)現(xiàn)一個(gè)錯(cuò)誤:提款金額應(yīng)在應(yīng)扣除的情況下添加到帳戶余額中。
更正錯(cuò)誤
要更正此錯(cuò)誤,請(qǐng)?jiān)贐ankAccount.cs文件中替換以下行:
m_balance += amount;和:
m_balance -= amount;
重新運(yùn)行測(cè)試
在“測(cè)試資源管理器”中,選擇“全部運(yùn)行”以重新運(yùn)行測(cè)試。 紅色/綠色條變?yōu)榫G色表示測(cè)試通過。
使用單元測(cè)試來改進(jìn)代碼
本節(jié)描述了迭代的分析,單元測(cè)試開發(fā)和重構(gòu)過程如何幫助您使生產(chǎn)代碼更健壯和有效。
分析問題
您已經(jīng)創(chuàng)建了一種測(cè)試方法,以確認(rèn)在借方方法中正確扣除了有效金額。 現(xiàn)在,如果借方金額為以下任一,則驗(yàn)證方法是否拋出ArgumentOutOfRangeException:
- 大于余額
- 小于零
創(chuàng)建并運(yùn)行新的測(cè)試方法
創(chuàng)建一種測(cè)試方法以在借方金額小于零時(shí)驗(yàn)證正確的行為:
[TestMethod] public void Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRange() { // Arrange double beginningBalance = 11.99; double debitAmount = -100.00; BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance); // Act and assert Assert.ThrowsException<System.ArgumentOutOfRangeException>(() => account.Debit(debitAmount)); }
使用ThrowsException方法斷言已引發(fā)正確的異常。除非引發(fā)ArgumentOutOfRangeException,否則此方法將導(dǎo)致測(cè)試失敗。如果您在借方金額小于零時(shí)臨時(shí)修改被測(cè)方法以引發(fā)更通用的ApplicationException,則該測(cè)試將正常運(yùn)行-即它將失敗。
要測(cè)試提取的金額大于余額的情況,請(qǐng)執(zhí)行以下步驟:
- 創(chuàng)建一個(gè)名為Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange的新測(cè)試方法。
- 將方法主體從Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRange復(fù)制到新方法。
- 將debitAmount設(shè)置為大于余額的數(shù)字。
運(yùn)行兩個(gè)測(cè)試并驗(yàn)證它們是否通過。
繼續(xù)分析
被測(cè)試的方法可以進(jìn)一步改進(jìn)。 在當(dāng)前的實(shí)現(xiàn)中,我們無法知道是哪個(gè)條件(金額> m_balance或金額<0)導(dǎo)致測(cè)試期間引發(fā)異常。 我們只知道ArgumentOutOfRangeException被拋出了方法中。 如果我們能說出BankAccount.Debit中的哪個(gè)條件引發(fā)了異常(金額> m_balance或金額<0),那會(huì)更好,因此可以確信我們的方法可以正確地檢查其參數(shù)。
再次查看正在測(cè)試的方法(BankAccount.Debit),請(qǐng)注意,兩個(gè)條件語句都使用ArgumentOutOfRangeException構(gòu)造函數(shù),該構(gòu)造函數(shù)僅將參數(shù)名稱作為參數(shù):
throw new ArgumentOutOfRangeException("amount");
您可以使用一個(gè)構(gòu)造函數(shù)來報(bào)告更豐富的信息:ArgumentOutOfRangeException(String,Object,String)包括參數(shù)名稱,參數(shù)值和用戶定義的消息。 您可以重構(gòu)被測(cè)方法以使用此構(gòu)造函數(shù)。 更好的是,您可以使用公開可用的類型成員來指定錯(cuò)誤。
重構(gòu)被測(cè)代碼
首先,在類范圍內(nèi)為錯(cuò)誤消息定義兩個(gè)常量。 將它們放在接受測(cè)試的班級(jí)BankAccount中:public const string DebitAmountExceedsBalanceMessage = "Debit amount exceeds balance"; public const string DebitAmountLessThanZeroMessage = "Debit amount is less than zero";然后,在Debit方法中修改兩個(gè)條件語句:
if (amount > m_balance) { throw new System.ArgumentOutOfRangeException("amount", amount, DebitAmountExceedsBalanceMessage); } if (amount < 0) { throw new System.ArgumentOutOfRangeException("amount", amount, DebitAmountLessThanZeroMessage); }
重構(gòu)測(cè)試方法
通過刪除對(duì)Assert.ThrowsException的調(diào)用來重構(gòu)測(cè)試方法。 將對(duì)Debit()的調(diào)用包裝在try / catch塊中,捕獲預(yù)期的特定異常,并驗(yàn)證其關(guān)聯(lián)消息。 StringAssert.Contains方法提供了比較兩個(gè)字符串的功能。
現(xiàn)在,Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange可能看起來像這樣:
[TestMethod] public void Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange() { // Arrange double beginningBalance = 11.99; double debitAmount = 20.0; BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance); // Act try { account.Debit(debitAmount); } catch (System.ArgumentOutOfRangeException e) { // Assert StringAssert.Contains(e.Message, BankAccount.DebitAmountExceedsBalanceMessage); } }
重新測(cè)試,重寫和重新分析
假設(shè)正在測(cè)試的方法中存在一個(gè)錯(cuò)誤,并且Debit方法甚至不會(huì)拋出ArgumentOutOfRangeException,別介意輸出帶有異常的正確消息。目前,測(cè)試方法無法處理這種情況。如果debitAmount值有效(即小于余額且大于零),則不會(huì)捕獲任何異常,因此不會(huì)觸發(fā)斷言。然而,測(cè)試方法通過了,這是不正常的,因?yàn)槿绻麤]有拋出異常,測(cè)試方法將失敗。
這是測(cè)試方法中的錯(cuò)誤。要解決此問題,請(qǐng)?jiān)跍y(cè)試方法的末尾添加Fail斷言,以處理沒有引發(fā)異常的情況。
重新運(yùn)行測(cè)試表明,如果捕獲到正確的異常,則測(cè)試現(xiàn)在將失敗。catch塊捕獲異常,但是該方法繼續(xù)執(zhí)行,并且在新的Fail斷言處失敗。若要解決此問題,在catch塊中的StringAssert之后添加return語句。 重新運(yùn)行測(cè)試可以確認(rèn)您已解決此問題。 Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange的最終版本如下所示:
[TestMethod] public void Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange() { // Arrange double beginningBalance = 11.99; double debitAmount = 20.0; BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance); // Act try { account.Debit(debitAmount); } catch (System.ArgumentOutOfRangeException e) { // Assert StringAssert.Contains(e.Message, BankAccount.DebitAmountExceedsBalanceMessage); return; } Assert.Fail("The expected exception was not thrown."); }
結(jié)論
測(cè)試代碼的改進(jìn)導(dǎo)致了更健壯和信息量更大的測(cè)試方法。但更重要的是,他們還改進(jìn)了受測(cè)代碼。
注意:本文內(nèi)容將Microsoft單元測(cè)試框架用于托管代碼。Test Explorer還可以從具有Test Explorer適配器的第三方單元測(cè)試框架中運(yùn)行測(cè)試。
本文內(nèi)容篇幅較長(zhǎng),分為上下兩篇,點(diǎn)擊可查看上篇>>
喜歡該產(chǎn)品的朋友可以點(diǎn)擊下載Visual Studio試用版免費(fèi)體驗(yàn)~
想要購買Visual Studio正版授權(quán),或了解更多產(chǎn)品信息請(qǐng)點(diǎn)擊【咨詢?cè)诰€客服】