Peter利用“類(lèi)是真實(shí)世界概念的自然抽象”這一理念作為自己觀(guān)點(diǎn)的基礎。他認為良好的單元測試 應該能夠驗證這些自然抽象出來(lái)的類(lèi),但可能在未來(lái)的某個(gè)時(shí)刻開(kāi)始,TDD和BDD將導致人們不去遵守這一原則:
我發(fā)現測試驅動(dòng)開(kāi)發(fā)(TDD)和行為驅動(dòng)開(kāi)發(fā)(BDD)這兩種方法結合在一起后存在一個(gè)問(wèn)題,那就是實(shí)踐者只把系統各部分間的交互放在了最核心的位置,其實(shí)并沒(méi)有做任何“單元測試”。他們只為了追隨TDD和BDD的魔咒,最后卻只見(jiàn)樹(shù)木、不見(jiàn)森林,而成為盲目測試。單元測試的目標是獨立的單元、應用程序中最小的可測試的部分。
Peter引用了Wikipedia's BDD entry中的一個(gè)例子來(lái)證明他的觀(guān)點(diǎn):
詳細的測試僅測了4,294,967,296種可能性中的13種。這些測試可能很好地測試了一個(gè)系統預期的行為,但是并沒(méi)有真正把EratosthenesPrimesCalculator當作一個(gè)單元來(lái)測試。如果系統只允許這樣的行為,那么這些測試可以證明系統是正常的。但是,如果EratosthenesPrimesCalculator超出了這13種行為而被使用的話(huà)(這也正是將代碼封裝成類(lèi)的目的:重用),那么它就算不是上已測試好的啦。
這個(gè)例子在很大程度上依賴(lài)于這樣一個(gè)觀(guān)點(diǎn)——一個(gè)單元的有效性/正確性完全是基于其名字所暗示的在現實(shí)世界中它所固有的特性。很多TDD的實(shí)踐者會(huì )向這一點(diǎn)發(fā)起挑戰,他們認為:一個(gè)單元的有效性只能在使用它的環(huán)境(系統)上下文中才能定義。JMock的作者之一Steve Freeman說(shuō)道:
測試先行的交互測試的思想是理清一個(gè)對象與它的環(huán)境之間的關(guān)系。例如,你正在模擬一個(gè)DAO,但是DAO不是應用領(lǐng)域中一部分,它是實(shí)現領(lǐng)域的一部分。
而另一方面,很多做TDD培訓的人會(huì )不認同這一點(diǎn),他們認為:先行編寫(xiě)單元測試的主要作用在于它是一個(gè)單元模塊該做什么、不該做什么的顯式規約。下面文字源自于Mario Gleichmann的“TDD與按契約設計的對比”:
單元測試作為測試驅動(dòng)開(kāi)發(fā)(TDD)的一個(gè)重要組成部分,其作用并不在于能在多大程度上驗證實(shí)現的正確性,而是有助于澄清單元模塊行為的規約。事實(shí)上,驅動(dòng)開(kāi)發(fā)的東西應該是規約,而不是驗證。你可以在行為驅動(dòng)開(kāi)發(fā)(BDD)的崛起中看到這種思想的回歸。BDD其實(shí)就是要尋找一個(gè)充分的詞匯表并用一種很自然的方式編寫(xiě)規約(當然,這也是可以被自動(dòng)化測試的),以便將注意力重新放到“組件在特定條件下應具有哪種行為”這個(gè)問(wèn)題上來(lái)。
從“單元模塊是由其上下文定義的”這種觀(guān)點(diǎn)中引申出來(lái)的一個(gè)推論經(jīng)常被引用,這個(gè)推論就是:按照單元測試的定義,它并不能反映出整體系統的質(zhì)量和有效性,相反,要想做到這一點(diǎn),就要在開(kāi)發(fā)階段中增加各種級別的驗收測試。JS Greenwood寫(xiě)道:
雖然集成測試少得可憐,但所有事情都被獨立測試過(guò)了——每一個(gè)組成部分都很干凈、獨立、被良好測試并且可以信任其正確性,(這也是單元測試的極限了)。但是如何保證所有組件都能協(xié)同工作呢?這是一個(gè)灰色(甚至黑色)區域,除非能充分地結合單元測試和集成測試。
原文轉自:http://kjueaiud.com