測試驅動開發實踐,測試驅動開發
總是以為自己瞭解了測試驅動開發,其實做起來和瞭解根本不是一回事。原來覺得代碼清晰得很,後來實驗了一下才知道那是自己的錯覺。這次,讓我們拋卻Eclipse的自動補全功能,來一場真正的測試驅動開發吧。
項目描述:這是一個很簡單的項目,目標是掃描磁碟上所有特定格式的檔案,將其路徑儲存下來,通過程式可以快捷搜尋到檔案路徑並自動定位到該檔案。
使用者故事(簡單點寫了):
1、 掃描磁碟,將目錄下的所有檔案列出來,將特定格式的檔案資訊儲存到磁碟。
2、 所有檔案的資訊可以被查詢。
3、 被查詢出的資訊可以雙擊開啟所在檔案夾並定位該檔案。
好了,這就是第一次的迭代目標,其中檔案的格式枚舉,儲存到磁碟的形式,都可以以後再說,那麼針對於故事的過程,我們開始設計並寫測試吧:
設計:
1、 一般檔案儲存,每個檔案以行為單位儲存,不同屬性以###分割,執行個體化到FileInfo類(故事1)。
2、 一般檔案叫fileDB。檔案以行讀取到List,以帶格式的String寫入(故事1)。
3、 特定檔案格式以Regex匹配(故事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吧。(未完……)