他舉了這樣一個例子,class X有一個叫作badMethod的方法,這個方法處理一些“痛苦”的工作,比如調用并更新產品數據庫、或者處理一些甚至關系到底層硬件的事務:
public class X { public void method() { ... badMethod(); ... } ...}
理想的設計是,系統可以允許獨立測試一般的類和類組。但如果這個例子沒有實現這樣的設計,“badMethod是個非final,可覆寫的方法”的事實就有利于為獲得“測試足夠的機動性”提供所需的靈活性,因為它允許“覆寫功能并為我們創建一個楔子來讓測試變得更簡單”:
public class TestableX extends X { void badMethod() { // do nothing } }
Feathers稱之為一個seam(接縫),“一個你無須修改便能使用一個功能替代另一個功能的地方”。他相信OO語言提供的緩綁定技術使得其本身比函數式語言的恢復更為友好。
一些評論者,包括Feathers本人在內,都強調了大多數語言都能提供seam的事實:預處理器、繼承/多態性和委派、宏和函數指針、高階函數、動態函數、一等函數、模塊邊界或monads。。。。。。其中一些人認為,真正關系到可測試性的是底層設計而非編程語言的選擇。比如John,他斷言,無論使用何種語言,“代碼的結構需要首先考慮到簡化單元測試!绷硪晃徊┛虯ndrew,強調說如果“代碼的結構沒有向所需的測試看齊的話”,那么實現將不得不向順應測試的方向,做相應的修改。因此,他也評論說“關于‘seam’的想法確確實實是瞄準了為實現可測試性而進行恰當設計的底層問題”,也就是說,適當地布置seam。
針對這些爭論,Feathers強調說,盡管大部分語言都擁有seam,但關鍵在于哪種語言用起來更為順手,尤其是在代碼未能以方便測試的方式而設計的情況下:
我同意“針對測試來設計”是真正的重點所在,但我也知道無論我們做什么,總會有一些系統沒有以這樣的方式來設計。也正是因為這個原因,我非常在乎可恢復性。
[…]
我知道設計seams是可能的,但那不是問題所在。真正的問題在于在它們沒有被加入進設計的情況下,而適當布置它們到底有多簡單。
[…]
當然,seams也不總是與你所想要實現的測試粒度相一致,毋庸置疑的是,在對seam具有良好支持的語言中,要實現與測試粒度相一致會簡單得多,因為seam已經存在那里,也因為它創建新的seam更為簡單。
根據Feathers所述,盡管在函數式語言中可以采用其他模型來達到同樣的目的,但“這是沉重的”,但Haskell例外。在Haskell中,“大部分你想在軟件測試中避免的代碼,都可以采用monad來實現”。
盡管Feathers著重指出,他知道人們會辯論說“純函數式可以滿足任何單元測試的需求”,但仍然有許多評論者強力辯論說他沒有考慮到函數式語言的細節,以及函數式語言所能提供的機會。Erikd表達了這樣一種感覺,他覺得Feathers是在將Java構造器和慣用方法運用到函數式代碼中去。
首先,他看上去是在使用Ocaml文法編寫Java代碼,然后又抱怨說Ocaml不夠像Java。他的結論一點都不驚人。Ocaml不是為了編寫類似Java這樣面向對象的代碼而設計的,就是這么簡單。
其次,他聲稱使用函數式語言比Java困難。雖然使用Ocaml文法編寫Java代碼可能確實很難,但是編寫一般的Ocaml代碼或函數式代碼就不會那么困難了。
很多函數式語言的擁護者強調說,在函數式編程中,是沒有副作用的,并且據Greg M.所說,這點可以預防寫出需要重構的代碼,而且可以將測試變得更為簡單:
文章來源于領測軟件測試網 http://www.kjueaiud.com/