測試驅動開發實踐


總是以為自己了解了測試驅動開發,其實做起來和了解根本不是一回事。原來覺得代碼清晰得很,后來試驗了一下才知道那是自己的錯覺。這次,讓我們拋卻Eclipse的自動補全功能,來一場真正的測試驅動開發吧。

項目描述:這是一個很簡單的項目,目標是掃描磁盤上所有特定格式的文件,將其路徑存儲下來,通過程序可以快捷搜索到文件路徑並自動定位到該文件。

用戶故事(簡單點寫了):

1、              掃描磁盤,將目錄下的所有文件列出來,將特定格式的文件信息存儲到磁盤。

2、              所有文件的信息可以被查詢。

3、              被查詢出的信息可以雙擊打開所在文件夾並定位該文件。

好了,這就是第一次的迭代目標,其中文件的格式枚舉,存儲到磁盤的形式,都可以以后再說,那么針對於故事的過程,我們開始設計並寫測試吧:

設計:

1、          平面文件存儲,每個文件以行為單位存儲,不同屬性以###分割,實例化到FileInfo類(故事1)。

2、          平面文件叫fileDB。文件以行讀取到List,以帶格式的String寫入(故事1)。

3、          特定文件格式以正則表達式匹配(故事1)。

4、          查詢的條件是文件名,通過遍歷List查找屬性是否符合contains規則(故事2)。

5、          用JNI explorer打開並定位文件(故事3)。

建立測試:

這里首先關注的是設計中的第一條。

新建一個Junit Test Case,我將測試的類叫FileInfo,所以這個測試類叫FileInfoTest,它與FileInfo在同一包路徑下,但是在不同的resource folder下。

這個Test Case應該不能通過測試。

事實證明,它的確無法通過測試

然后,它應該這樣被初始化。

編譯錯誤!那當然,因為類FileInfo還不存在,讓我們建立它。

編譯通過了,我們需要它將字段輸出成一個帶###分隔符的字符串,字符串的組成是FileName###FileDir###FilePath###LastUpdate。

那么測試應該變成這樣了:

為了解決這些紅杠,FileInfo得變成這樣。

(這里有那么一點點牽強,就是get方法和成員變量的來源不是“剛剛好通過測試”,而是測試原本是為了引出成員變量)

現在toString應該變成這樣:a.txt###c:\\###c:\\a.txt###2016-01-01。

所以測試應該變成這樣(這樣寫代碼好費時間!但參與設計的過程也相應變多,思考和工作量都在增長)

當然,測試失敗了,二者並不相等

 

 

原因當然在toString

修改FileInfo的toString方法:

測試通過了!

此時,我在想,如果因為某種原因,我想將###換成@@@,那么toString方法中###應該以變量的形式出現。但因為此次將修改的代碼對通過測試沒有任何意義,也不能增加功能,所以我不這么做。我會在什么時候這樣做呢?我會等到代碼的功能很多,我重構它並能展示此時測試對我重構的意義的時候。

現在我們完成了設計1,來開始設計2吧。

將fileDB.txt建立在項目根路徑下,為了便於之后的測試,寫入如下內容:fileName###fileDir###filePath###lastUpdate。

然后新建一個測試類,用於測試還沒有建立的類是否能讀取fileDB並且按行存儲到List。

那么測試類應該是這個樣子:

讓它通過編譯。必要時,甚至可以遵從Eclipse建議的做法。

執行測試,報錯。

List.get(0)的問題,list是空的,那么,讓我們放點東西進去。

這算什么!這不就是騙人的嗎?但是我剛好通過了測試的問題,現在進入測試的下一個問題。

 

 

現在是將fileDB.txt讀取,並放入數據的時候了。但此時我們好像需要額外的幾個方法。

 

好像聞到了代碼的異味,但是測試通過了。很可惜,我不知道這種情況應該怎么處理,所以我決定改變測試以來改變代碼!

 

好了,讓我們再次恰恰好通過測試吧。另外,我們可能還需要readFileToList和getFileList的測試。剛剛我們好像忘記了,如果測試類調用了某個實例的方法,我們應該首先對實例的方法進行測試編碼。

 

怎么辦怎么辦?我沒法解釋這個私有方法的由來,這是我重構本能決定的,和測試沒有任何關系。這里應該是我對TDD理解不深的地方。

 

測試通過了。我能料到以后如果getFileInfoByLine的規則變化的話,這個私有方法還沒有被測試覆蓋,是一個隱患,但是現在該怎么辦呢?因為它是私有的,甚至無法被其他類調用。

好吧,既然它是私有的,那么暫時就只保證所有調用它的方法測試通過吧。

就此,我們完成了第二個設計。這時候我發現一個嚴重的問題,就是我的設計沒有覆蓋用戶故事中的對磁盤的掃描。

目前為止,這個不嚴謹的實踐也告訴我們,如果對TDD和敏捷理解不深,隨時會似是而非最終偏離航道的。

(未完……)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM