代碼更加容易被理解 單元測(cè)試的好處通常并非是人們最初所期待的,在一個(gè)工程中考慮修改一些你之前從沒(méi)有看過(guò)的代碼(比方說(shuō),一個(gè)特殊的類或者方法).你將如何動(dòng)手處理這些代碼?你可能需要在項(xiàng)目中去瀏覽這些特定的類或者方法使用的代碼,理所當(dāng)然,單元測(cè)試就是這樣例子的一個(gè)很好的場(chǎng)所。同時(shí),當(dāng)正確寫(xiě)入的時(shí)候,單元測(cè)試可以為工程提供一個(gè)API文件的容易讀取的設(shè)置,使得文檔的處理和代碼的理解對(duì)于整個(gè)團(tuán)隊(duì)中的新老開(kāi)發(fā)者一樣的簡(jiǎn)單,便捷。然而,這些只能在測(cè)試是易讀的和容易理解的情況下才能被確認(rèn),這個(gè)規(guī)則很多的單元測(cè)試開(kāi)發(fā)者并不會(huì)遵循。我將詳述這個(gè)信任,然后在這篇文章的易讀測(cè)試的部分給你展現(xiàn)如何在去寫(xiě)易讀的單元測(cè)試。
測(cè)試正確的事情
新來(lái)者在Test Driven Development (TDD)中一個(gè)最通常的錯(cuò)誤就是他們通常會(huì)搞混"Fail by testing something illogical."中的"Fail first"要求。例如,你可以用下面的規(guī)格開(kāi)始這個(gè)方法: ' returns the sum of the two numbers
Function Sum(ByVal a As Integer, ByVal b As Integer) As Integer
你可以向如下的方式寫(xiě)一個(gè)失敗測(cè)試: <TestMethod()> _
Public Sub Sum_AddsOneAndTwo()
Dim result As Integer = Sum(1, 2)
Assert.AreEqual(4, result, "bad sum");
End Sub
初看上去這個(gè)處理像是一個(gè)寫(xiě)失敗測(cè)試的好的方法,它完全錯(cuò)失了你寫(xiě)錯(cuò)誤測(cè)試的初始點(diǎn)。
一個(gè)失敗測(cè)試驗(yàn)證了在代碼中存在一些錯(cuò)誤,當(dāng)你的測(cè)試完成后這個(gè)測(cè)試應(yīng)該是通過(guò)的,現(xiàn)在的例子中,無(wú)論如何,測(cè)試都將會(huì)失敗,即使是代碼完成,因?yàn)闇y(cè)試邏輯上不是正確的。如果希望測(cè)試通過(guò)測(cè)需要測(cè)試自身進(jìn)行修改――而不是程序的代碼的改變(當(dāng)程序代碼改變的時(shí)候,是test-first規(guī)劃的意圖)簡(jiǎn)短來(lái)說(shuō),這個(gè)測(cè)試不會(huì)反映出程序代碼完成后的最終的結(jié)果,因此這個(gè)不是一個(gè)好的測(cè)試。 單元測(cè)試小技巧[2]http://www.csai.cn 作者:Roy Osherove 來(lái)源:MSND 2007年1月24日
TDD中一個(gè)好的測(cè)試要求你去修改代碼,從而使它能夠按照想要的方式工作,這一點(diǎn)要?jiǎng)儆趶?qiáng)迫你去反映現(xiàn)在的真實(shí)情況或者一個(gè)非邏輯要求的渴望的結(jié)果。例如,當(dāng)1+1返回0時(shí)就意味著測(cè)試失敗。這個(gè)簡(jiǎn)單的例子和這種情況是相似的,在練習(xí)中,如果現(xiàn)在的需求是在工作的,測(cè)試應(yīng)該可以反映你所期待的結(jié)果,然后你可以調(diào)整現(xiàn)在代碼的情況去通過(guò)這個(gè)測(cè)試。
作為一個(gè)規(guī)則,一個(gè)已經(jīng)調(diào)通的測(cè)試不應(yīng)該被移除掉,因?yàn)檫@個(gè)測(cè)試在維護(hù)工作中可以用于恢復(fù)測(cè)試。他們?cè)谀愀淖兇a時(shí)用來(lái)確定你沒(méi)有損害到現(xiàn)在已經(jīng)工作的函數(shù)。這就是為什么你不應(yīng)該修改那些已經(jīng)通過(guò)的測(cè)試,除非是一些很小的修改,例如增加它的可讀性(換句話說(shuō),分解測(cè)試)
當(dāng)一個(gè)測(cè)試非正常失敗 有時(shí)你可能遇到失敗的測(cè)試,而這時(shí)你對(duì)代碼的改變是完全合理的。這通常是因?yàn)槟阌龅搅藳_突的需求。一般來(lái)說(shuō),可能是一個(gè)新的需求(一個(gè)改變的特性)與一個(gè)舊的可能已經(jīng)不再有效的需求發(fā)生了沖突。這有兩種可能:
1. 在舊的需求或者無(wú)效或者在別處測(cè)試的情況下刪除被驗(yàn)證本質(zhì)上不再有效的失敗的測(cè)試
2. 改變舊的測(cè)試使你可以測(cè)試新的要求(本質(zhì)上使用新的測(cè)試),然后在新的設(shè)置下(測(cè)試的邏輯狀態(tài)相同,但是初始功能函數(shù)可能有所不同)測(cè)試舊的需求。
而有時(shí)候一個(gè)測(cè)試在使用不完整的技術(shù)去完成任務(wù)的時(shí)候也是有效的,例如,你有一個(gè)成員類帶有一個(gè)FOO方法,它表現(xiàn)為某幾種行為,它已經(jīng)經(jīng)由Test在X年前測(cè)試完成,然后現(xiàn)在一些其他的需求加了進(jìn)來(lái),方法的邏輯增強(qiáng)了,從而可以去處理一些類似于在獲取數(shù)據(jù)時(shí)丟失一些參數(shù)的異常處理。但這時(shí),突然Test X失敗了,雖然在測(cè)試這個(gè)函數(shù)的時(shí)候只是使用了同樣的類。這個(gè)測(cè)試的失敗是因?yàn)樵谡{(diào)用方法之前丟失了一些初始處理步驟。
這并不意味著你需要移除Test X,你將丟失對(duì)于一些重要功能的測(cè)試,這時(shí)你應(yīng)該去關(guān)心那些初始化時(shí)的問(wèn)題,而不是改變類的創(chuàng)建以用來(lái)適應(yīng)你新的意圖。
當(dāng)然如果你那里有200個(gè)測(cè)試都是因?yàn)榕f的結(jié)構(gòu)導(dǎo)致的失敗,你就應(yīng)該找到這個(gè)問(wèn)題來(lái)維護(hù)你的測(cè)試。這就是為什么你應(yīng)該總是移除你測(cè)試中的副本尤其是在生產(chǎn)代碼中。
測(cè)試覆蓋和測(cè)試Angles 你如何知道是否你的新代碼是一個(gè)好的覆蓋?當(dāng)試圖移動(dòng)一個(gè)鏈接或者一個(gè)約束檢查后,如果所有的測(cè)試依然通過(guò),那么你就沒(méi)有足夠的代碼復(fù)制然后你可能需要添加其他的測(cè)試單元。
確認(rèn)你添加正確測(cè)試的最好方法就是測(cè)試一些最平常的行和檢查直到用非常的手段使它出錯(cuò)。這個(gè)也許很難,但是如果你不能考慮出一個(gè)讓代碼出錯(cuò)的方法,你就可能沒(méi)有好的理由在最初的地方寫(xiě)下這行代碼。
更多軟考資料請(qǐng)?jiān)L問(wèn):考試吧軟件水平考試欄目
希望與更多網(wǎng)友交流,請(qǐng)進(jìn)入考試吧軟件水平考試論壇
北京 | 天津 | 上海 | 江蘇 | 山東 |
安徽 | 浙江 | 江西 | 福建 | 深圳 |
廣東 | 河北 | 湖南 | 廣西 | 河南 |
海南 | 湖北 | 四川 | 重慶 | 云南 |
貴州 | 西藏 | 新疆 | 陜西 | 山西 |
寧夏 | 甘肅 | 青海 | 遼寧 | 吉林 |
黑龍江 | 內(nèi)蒙古 |